Socket Programming tutorial

Friday, July 4, 2008

Generic Socket Programming tutorial

S.Prasanna
sprasanna199@gmail.com

This is a generic socket programming tutorial which mainly concentrates on how to communicate with two machines using TCP/IP and UDP/IP protocols irrespective of the programming language used to implement the server and client

I will list a simple Connection oriented (TCP) and Connectionless (UDP) Server and Client programs for all the four languages namely Python , Perl, C and Java. The TCP Server program is an iterative one which means it will process clients one by one. The communication between the TCP Server and the Client is a simple chat program. If the client quits, the current TCP connection between the server and the client gets disconnected and the server processes the next client and if the server decides to quit, that client gets disconnected and the server processes the next client.

The UDP Server program is very simple. The server recieves datagrams from many clients and prints them.

In all the programs , the Server process listens at port 5000 and I have used loopback address for the Server so that you can run the server and the client in different terminals in the same system. Besides you can use any of the four servers implemented in Python , Perl, C and Java with any of the four client programs implemented inthe four languages.In short you can use a Client program in Perl with a Server program in python , Server program in python with a Client progam in C , etc. Morever you can invoke the client program without any command line arguments since the client and the server are designed to communicate using the loopback address.

I will go from easy to difficult ( in terms of readability and lines of code ). i.e for example socket programming is simple and easy to understand in Python than in C or java.


1. Socket programming in Python

Connection oriented Server and Client program.

tcpserver.py and tcpclient.py

Connectionless Server and Client program.

udpserver.py and udpclient.py


2. Socket programming in Perl

Connection oriented Server and Client program.

tcpserver.pl and tcpclient.pl

Connectionless Server and Client program.

udpserver.pl and udpclient.pl


3. Socket programming in C

Connection oriented Server and Client program.

tcpserver.c and tcpclient.c

Connectionless Server and Client program.

udpserver.c and udpclient.c


4. Socket programming in Java

Connection oriented Server and Client program.

TCPServer.java and TCPClient.java

Connectionless Server and Client program.

UDPServer.java and UDPClient.java


I will list similar programs in as many languages in future. I could have explained about the details of sockets, how system calls like socket , bind, listen, etc works, but those should be explained from the perspectives different languages which is beyond the scope of this tutorial. In general these programs explain the fundamental concepts of socket programming irrespective of their implementation language.

Socket programming can be easily understood in interpreted languages like Perl and Python. Perl, especially is weapon for hackers. Dangerous scripts can be developed in minutes, in perl. For example spoofing source IP address can easliy be done in Perl but it requires some effort in C or in other languages. This small script shows how to spoof UDP source address.

Raw Sockets Programming (UDP Spoofing):

udpspoof.pl and udpserver.c

When you run the above simple script as client you can see the fake IP source address and the port the client used at the UDPServer. To execute the Perl script you need the Net::RawIP Module which can be downloaded here and also its documentation.

TCP/IP spoofing is a challenging task and involves a lot of calculation involving prediction of sequence numbers,etc but worth giving a try.

References:

1. Beej's guide to Network Programming

The highly rated Socket Programming tutorial in the Web. It explains all system calls used for socket programming in a clear way and also about Networking concepts in general.

2. UNIX Sockets for Newbies

Another Wonderful Socket programming tutorial.

3. Network Programming in Python

An excellent document on Python Socket programming.

4. UNIX Sockets FAQ

Answers to common questions asked by socket programmers.

5. Perl Socket Programming tutorial

Good introduction to Perl sockets.

6. http://pont.net/socket/index.html

A Collection of different Client-Server programs in C and Java.

74 comments:

FOF-ff said...

Thank you this helped so much!, i'm in the works of making an offline game , online, the game is called frets on fire, and its like "guitar hero" so for multi player i need it to send the score, do you know how to make the client send the score from one client to my server to another client? and vice versa?

Prasanna Seshadri said...

Thats a good question, I have done it in the past, having many clients and a server with clients exchanging messages through the server.

Watch out my blog, I will post that solution in a couple of days, which is pretty easy.

FOF-ff said...

thanks cant wait :)

FOF-ff said...

also im using java as the server, and pythong client(s)

Prasanna Seshadri said...

Sure, mine will be in python (both clients and server part), I am sure it will be very useful to you, its in testing stage right now, but will be done early this week.

Prasanna Seshadri said...

Hi,

Heres what you're looking for, I have written a tutorial on using asynchronous I/O using python sockets which will solve your problem.
http://www.prasannatech.net/2008/07/asynchronous-sock

Anonymous said...

I am new to socket programming and wanted to understand the communication of a client with a server of different technology. This article was useful. Thanks.

BTW..the link in your response to FOF-ff is incorrect. Heres the correct link
http://www.prasannatech.net/2008/07/asynchronous-socket-programming-select.html

Prasanna Seshadri said...

Glad that it was useful to you, I will change that link for sure.

Dileep said...

Hi,
I am new to socket programming. I am trying the code that you have given for client and server for windows. But the problem I am facing is there is no socket.h file in my system. Plase tell me how can I proceed in this situation

Thanks
Dileep Kumar

Prasanna Seshadri said...

Hi Dileep,

The socket code in C is mainly for Unix/Linux environments, however for making it work in windows, you may try Cygwin GCC compiler(www.cygwin.org).

Anonymous said...

Best client/server page I've run across over a long time of Googling.

Very good job.

Prasanna Seshadri said...

Thanks for saying so :)

Vince said...

Thank you Mr.Prasanna
I'm newbie for socket programming.
I'm so glad to found such good sample for TCP server and client. I was looking for it few days already but cant find satisfy one. Others are not work or too hard to debug. Thanks for your afford

Sincerely,
Vince

Prasanna Seshadri said...

Thanks Vince for saying so, glad that you found it useful.

kakesblog said...

hello sir,
sir I'm a newbie to socket programming. Can you suggest me some books or tutorials which will help me in understanding socket programming in C language for TCP sockets.That will be a great help .

Prasanna Seshadri said...

Hi,

If you are a newbie, the best thing you can do is to refer some of the online tutorials which I mentioned in the reference column, once you have a grasp of the fundamental concepts, the following books may be useful.

1. Java Network Programming, Third Edition by Elliotte Harold (Author), Elliotte Rusty Harold

If you are Java centric.

2. Unix Network Programming, Volume 1: The Sockets Networking API (3rd Edition) (Addison-Wesley Professional Computing Series) by W. Richard Stevens

If you interested in core socket programming in C.

You can get these from Amazon.

Stingers Destiny said...

Hi
Thanks for the programs. I am trying to use Java (Server) and Python (CLient) but somehow i cant get it to work with the message from Server to Client back.

The problem is the same when i reverse the CLient (to Java) and server (to Python)

Is it to with flush or something..??

Prasanna Seshadri said...

Hi,

Thanks a lot for pointing out, yes it may be a flush issue, I will ensure that I change the java IO stream to the right one to make it work.

Would fix that soon and let you know.

Sunny said...

Thanks this is great.
Do you have a version of this written for windows using c.
Thanks.

Sunny said...

Never mind. I was able to compile the code in windows by making a few changes.
First off I added #include WinSock2.h
Next Used memset instead of bzero and used closesocket instead of close.

I did all this easily but faced a issue of code not compiling in Visual Studio. I was getting some wierd linking errors....error LNK2001: unresolved external symbol __imp__WSAStartup and then I found this article (http://msdn.microsoft.com/en-us/library/ms737629(VS.85).aspx#) which tells how to fix it. Basically I had to link WS2_32.lib in the build environment. The link talks about how to do it.

Prasanna Seshadri said...

Hi,

Glad that you solved your issue, I had a tough time in the past trying to compile socket code in Windows, yes you need to link some libraries.

Because of some issues I faced similar to what you have been facing, I switched to Linux, you can always use Cygwin to run your socket code in Windows unless its a VC++ Project you are working on or use scripting languages to code sockets.

I am also considering to have one windows version to make this complete, not sure when will I be able to do it, probably when time permits.

Sunny said...

Hi,
Can you tell me how do I use recv to read data sent to my client from server. The server is sending ACK (1\r\n... when data from client is received by server) and then followed by a status message which is result of server doing some command calls.

I need a way to get ACK to validate data over the socket was received by server and then get the status message from the server on the client.

Thanks for your help.

Prasanna Seshadri said...

Hi,

I got your problem, first my question is are you trying to send an ACK to the client to acknowledge the client request, in case you are using tcp socket this is not needed since its a guaranteed transfer protocol in which case a reply from the server to a particular client means that it got the command status.

If you are still using ACK, then have recv() call, then check the recv string, if its ACK string wait for another recv to get the status, on the other hand if any of the recv() calls throws an exception "Connection reset by peer" when the server closes the connection with the client, then close the client socket and exit.

Let me know if this helps.

Look at my C socket code on how this is done, in windows also it would be the same.

Anonymous said...

Hi , I was looking for Async Tcp server in python..I guess the link http://www.prasannatech.net/2008/07/asynchronous-sock
is broken, could be please post the program, thanks a load

Prasanna Seshadri said...

Hi,

You can easily find that section, in the top left labels section, click on socket programming, you can find three articles, one on socket programming and the other were asynchronous socket programming in python, somehow posting link in the comment section doesn't work properly.

Anonymous said...

Hi Prasanna.

Please help me in finding out the server status through java programming

Prasanna Seshadri said...

Hi,

For more info on return codes in sockets in java, do refer the official Socket java class doc here.

http://java.sun.com/j2se/1.4.2/docs/api/java/net/Socket.html

Anonymous said...

thanks Prasanna for your kind reply

php application development said...

Nice post prasanna, keep it up dude!!!!

Prasanna Seshadri said...

Thanks a lot for saying so, Welcome.

Vasu said...

hi prasanna seshadri..This is vasu from hyderabad,india..I am doing a project on WEB APPLICATION SECURITY SCANNER.SO i need to do some socket programming to connect to remote WEB SERVER.
Can u please tell me in which language(java or c) the socket programming is efficient,robust and easy to implement.Waiting for ur reply..

Prasanna Seshadri said...

Hi Vasu,

For your application, the best language would be java, java has excellent built in modules to implement web server and some security APIs as well to design your web application scanner, do look at the book "Java Security" by Oreilly which may be useful for you.

Krishnamachchaari said...

Hi Prasanna,

I am a newbie to socket programming. I am trying to design a server that can store a customers name, password and balance. I thought of writing these in a separate txt file after strtok() for removing all the commas. But i think the program will be slow due to the operations it has to do. Is there any better way to do this?

Prasanna Seshadri said...

Hi,

It all depends on how many customers you are handling, if its large, then it would cause huge performance hit in retrieving a customer data if you write it this way, in which case you should use a light weight DB.

Another more way to solve this is to have individual text files for each customer identified by a unique ID derived from their name and other details (like SSN) and store it in the text file, doing this way would make it easy to retrieve the customer details from that file based on name/balance or other unique detail for that customer, also it you want to delete that customer's record, its just a matter of deleting that file alone.

aya ibrahim said...

hi,
I'm student in faculty of computers and information and I'm new in Socket programming in java
i have question,
how I can divide video on the client into packets and send packets to server
Really i need your respond,it is very important to me

Prasanna Seshadri said...

To send video to server, use an InputStream like BufferedInput Stream and fetch the video binary contents in a buffer and then transfer them to the server, do look at the java code I have used to transfer bytes through socket, if you have doubts, let me know.

Anonymous said...

Hi Prasanna

I am satya, I have one problem ,how can I send or receive numeric values to client/server. what is the function to send numeric values to server/client.

Prasanna Seshadri said...

Hi Satya,

The solution to transfer numeric values is quite simple, you just need to convert the numbers into string using functions like toString in java or str in python, in C there is an itoa function to do the same, you can always get the number back from string using the reverse function like atoi in C, int() in python, Integer.getInteger method in java.

Sunny said...

Hi Prasanna,
Please refer to my comment posted on November 10, 2008 4:13 PM and your reply.

So my client has a recv() call after the send and it always bring back 1/r/n (ACK). Then I do another recv() to get the message back from the server. On most of the scenarios this works perfect but in some cases the client gets nothing from the server because the server has not put the message on the socket. I am trying to fix this to get the message in second recv() call (since the first recv() call brings back ACK).

So I added a timeout to the recv() call as described in Beej's guide. This works fine but now the client always wait the timeout seconds before the reply is sent. So, if I set the timeout to be 4 seconds, I get a reply from my client exactly after 4 seconds. I was hoping to get the message back as soon as it was on socket.

I was reading something for non-blocking that would do this kind of thing but I am new to this and could not get much.

Do you have any recommendations. Here is the code I have without the timeout implemented in recv().

iResult = send(sock,send_data,strlen(send_data), 0);
if (iResult == SOCKET_ERROR)
{
closesocket(sock);
return RETURN_ERROR; //store transactions as offline transaction.
}

// read socket for ACK from Integrator
bytes_recieved = recv(sock,recv_data,SOCK_MAX_SEND_RECEIVE,0);
if(bytes_recieved == SOCKET_ERROR)
{
closesocket(sock);
return RETURN_ERROR; //store transactions as offline transaction.
}


if(strcmp(recv_data,"1\\r\\n")) //ACK received
{
bytes_recieved = recv(sock,recv_data,SOCK_MAX_SEND_RECEIVE,0); //second recv()
if(bytes_recieved == SOCKET_ERROR)
{
closesocket(sock);
return RETURN_ERROR; //store transactions as offline transaction.
}
else if (bytes_recieved >0)
{
//print the message out
}
}

Sunny said...

Do you have an example of non-blocking sockets and recv(call working together?

Thanks.

Sunny said...

Hi again,
I tired the following as described by Microsoft (MSDN) but I get a crash when recv() is called for second time in the loop. I guess there is no data on the socket to receive during the second call but I am not sure how to handle it.

// Receive until the peer closes the connection
do {

iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
if ( iResult > 0 )
printf("Bytes received: %d\n", iResult);
else if ( iResult == 0 )
printf("Connection closed\n");
else
printf("recv failed: %d\n", WSAGetLastError());

} while( iResult > 0 );

Prasanna Seshadri said...

Hi,

You need to handle recv for exceptions as well, I had a writing on non-blocking sockets in python here, where I handled recv call and the possible exceptions it can throw, do look at it here

http://www.prasannatech.net/2008/08/non-blocking-sockets.html

I think the code for C is similar, if you hit the walls, let me know.

Note that the behavior of recv exception is different in Unix and Windows, look at the code for non-blocking sockets which will make things clear for you.

Anonymous said...

I wan to make a project wich is named VOIP(voice over internet protocol)..n i need to use socket programming for dat..kindly tell me where i shud start from..pls post me some tutorials dat can give a basic knowledge about this concept.

Vishmadev said...

hi prasanna i am having a problem with connect function...
i dont know why...
i m giving u the code here..plz help me...

int main(int argc, char *argv[])
{

struct MSG {

long int m_type;
int m_txt[MAX_TEXT];
int m_seq;
int m_total_packet;

} m_data;



int sock,conn;
struct sockaddr_in server_addr,client_addr;
int bytes_sent, buffer_length,rcvack=1;


FILE *in;
int f,j=1,k,i;


int total_packet_no=0;
fpos_t pos;
int c;
int size=0;
int nread,len,tran_data;

//argument checking
if(argc!=3)
{
printf("Please enter like the following\n");
printf("./msgtx /path/filename IP Address\n");
exit(1);
}


//opening any file
if((in=fopen(argv[1], "r"))==NULL)

{
printf("Cannot open source file.\n");
exit(1);
}


//calculating the size of the file

while((c=fgetc(in))!=EOF)
size++;

fclose(in);

//calculating the no. of packets

total_packet_no=(size/MAX_TEXT)+1;
printf("total number of packets: %d\n",total_packet_no);
m_data.m_total_packet=total_packet_no;

sleep(2);

//again opening the same file, since rewind is not working, or stat

if((in=fopen(argv[1], "r"))==NULL)
{
printf("Cannot open source file.\n");
exit(1);
}

//converting the file pointer into file descriptor
f=fileno(in);
if ((sock=socket(AF_INET,SOCK_STREAM,0)==-1))
{
perror("Socket");
exit(1);
}

server_addr.sin_family = AF_INET;
inet_pton(AF_INET, argv[2], &(server_addr.sin_addr));
server_addr.sin_port =htons(5050);
bzero(&server_addr.sin_zero,8);
//memset(&server_addr.sin_zero,0,8);
len=sizeof(struct sockaddr_in);


if ((conn=connect(sock,(struct sockaddr *)&server_addr,sizeof(struct sockaddr)))< 0)
{
printf("error entered");
getchar();
perror("Connect");
exit(1);
}

while(j <= total_packet_no && rcvack > 0)
{
// sleep(1);
nread=read(f,m_data.m_txt,MAX_TEXT);
if(nread==-1)
{
printf("read error\n");
exit(1);
}

m_data.m_seq=j;
//displaying the data

bytes_sent = send(sock,(void*)&m_data, sizeof(struct MSG),0);

if(bytes_sent < 0)
{
printf("Error sending packet: %s\n", strerror(errno) );
exit(1);
}

j++;

}

close(sock);
fclose(in);

exit(0);
}



the problem is i am having an error like...socket operation on non-socket...
can u help me out...the server program is okay...)

satya said...

Hi prasanna
this is satya. I want to know how can we execute a unix command at server (c lan) and sent back that result to client and client will disply that result on stdout. we will take command at client, client send that command to server.
please help me out.
thank you
satya

Prasanna Seshadri said...

Hi,

Thats very simple, send the command as a string to the server and use a command like execl (or other exec command) in the server to execute the client command and add the result in a String array and send it to the client.

If you follow my C Code, the client sends a line to the server and replace that line by your UNIX command.

satya said...

if u don't mind can u give just simple code for execl command

satya said...

include stdio.h
include unistd.h
int main()
{
char buf[20];
bzero(buf,20);
printf("Here are the files in:%s",getcwd(buf,20));
execl("/bin/ls","ls","-al",NULL);
return 0;
}

this code is working fine, now how we can redirect this output to a sting instead of Stdout. we can send the string to client.

Prasanna Seshadri said...

Hi,

You have to use popen and pclose for getting the output and status code, I will write a separate section for that, but for the time being use this code.

#include &ltlstdio.h>
#include <stdlib.h>

int main(int argv, char ** argc) {

if (argv != 2) {
printf("Usage: unix_command \"COMMAND TO BE EXECUTED\"");
exit(1);
}

char *COMMAND = argc[1],*readLine, *tmp, *commandResult = "";
FILE * fp;
int status;

fp = popen(COMMAND, "w");

if (fp == NULL) {
perror("Command execution failed");
exit(1);
}

printf("Printing the command output....\n");
while ((fscanf(fp, "%s", &readLine)) != EOF) {
tmp = (char *) realloc(commandResult, strlen(readLine));
commandResult = tmp;
strcpy(commandResult, readLine);
}
printf("\nCommand %s output = %s", COMMAND, commandResult);
status = pclose(fp);
printf ("Command %s return status code = %d\n", COMMAND, status >> 8);
return status;
}

chits said...

hi prasanna ...
i need to send a text file from one system to another ... could u plz help me out ... could u give me the code ...

chits said...

that file transmission should be in socket programming (JAVA)

Prasanna Seshadri said...

Hi,

For transferring files, you may also look at my file upload server which transfers files from client to server which uses java sockets internally.

http://www.prasannatech.net/2009/03/java-http-post-file-upload-server.html

Wirasto S. Karim said...

Thank's

srikanth said...

how to create google addsence account ..
please explain in detail i am intreasted in it but confusing
and
thanks for socket programing tutorial

Prasanna Seshadri said...

Hi,

Would appreciate if you post comments related to adsense in my adsense related post, anyways creating adsense account is very easy, go to adsense.google.com and create one, you need to have a website/blog to create one.

satya said...

hi prasanna

please check this code
char buffer[30];
buffer="ls";
strcat(buffer,"> temp");
system(buffer);
if((fp=fopen("temp","r"))=NULL)

no compliation errors, but this command not writing anything into the temp file. can u check it once again. This is for executing a unix command at server machine and sent back the result to the client.

namratha said...

hello Sir,
I am new to socket programming. I hav taken up a project "implementation of FTP" . I heard that socket programming is necessary for it.
Please guide me what all knowledge should i have, to make my move.
Thank you

Prasanna Seshadri said...

Hi Namratha,

Your first step should be understanding all socket calls, just go through the above code, it will be a right start for you, if you want to feel easy, then I would recommend starting socket programming in a language like java or python, then use C.

There are lots of tutorials and books which may help you for this, once you learn, then FTP will be quite simple.

Prasanna Seshadri said...

For those of you who want to clarify doubts, be specific and clear, also I may not answer all queries because of time constraints, but will try to answer as many as possible.

Hema said...

hai im ramesh,
how to create a connection between the ethernet in a biometric reader with the computer!... here computer acts as a server and the ethernet in reader acts as a client!.. can u tell me how to establish connection between these two systems?
plz guide me prasanna can u give code in "c" for this case?

Prasanna Seshadri said...

Hi,

I am not sure about device driver communication between computers, they have a separate protocol to initiate the connection after the device is detected, you need to go through their manual to get more info.

hema said...

Many thanks prasanna..i.ve gone thro the manuals the ethernet controller we are using is W5100 which is already been interfaced with a ARM controller in the reader,. here we hav to transfer data thro that ethernet by tcp-ip mode to the pc for the finger print enrollment! moreover you are doing a good job for everyone
regards,
hemanandharamesh

Prasanna Seshadri said...

Hi,

Thanks for saying so.

satya said...

int main(int argc, char *argv[])
{
struct hostent *hp;
if(argc !=2) {
fprintf(stderr,"usage: getip address\n");
exit(1);
}
if ((hp=gethostbyname(argv[1])) == NULL) {
herror("gethostbyname");
exit(1);
}
printf("Host name :%s\n",hp->h_name);
printf("IP Address : %s\n",inet_ntoa(*((struct in_addr*)hp->h_addr))) ;
return 0;
}

when I am compleing this code I am getting dereferencing pointer to incomplete type. please help me what the changes I have to make.

thank you
with regards
satya
9291488346

Dileep said...

how to create http packets of video data on server side and how to determine relationship b/t that packets on client side

please give me any solution or suggest me about that problem
thanks in advance

Anonymous said...

I have a problem here.... I use cygwin under windows.. So I get the following problems:

1. When i go gcc client.c, it compiles well. But, when i click on the client.exe, it says the cygwin1.dll is missing

2. When i type $gcc client.exe client.c mno-cygwin, it says tht the sys/socket.h and netint/in.h are missing

What should i do to rectify this problem?

Prasanna Seshadri said...

Did you follow the cygwin manual, you should not be getting the dll errors if you installed cygwin properly, one thing which will help is copy the DLL in the same folder as your executable, that may solve the problem.

Jan said...

He Prasanna,

First of all, thank you for the good post.

I tried to communicate between the java udp server en de c udp client and with no problems.
But when i try to run de java tcp server with the c tcp client it doesnt work. When i run the client the console does not ask about anything to write. its just black and im not able to type anything.

You have any idea what it could be?
Many thanks

Prasanna Seshadri said...

Hi,

Yes I need to work on the Java C combination, when I find time will do that , looks like I need to use a different stream in that case.

Jan said...

thats ok i'm just using the UDP socket now.
But i have another problem. I'm sending information from the c client to the java server. In the java server everything is being put into arrays.
This is going just fine untill 574 times(i've put a counter in it) and then it stops getting anything. But the C client keeps on sending.
In java there is no error message or anything. It keeps running but does nothing.
Any ideas?

Prasanna Seshadri said...

You mean in my code above, let me know so that I can fix it this week when I am free.

Jan said...

Yes in the code you posted above. With the C UDP client sending to the java UDP server.
I also changed the code in the C client at line 24 and 25 to "return 0;" so it keeps on sending.(else it stops after a couple of times).
In java i just have data being put to an array that keeps getting overwritten.
I just can't find what the problem is.

Jan said...

Hej Prasanna I'm very close to the solution now. Where i said i put return 0; i raplaced that with close(0);(line 22 and 23. Earlier i said 24/25 my bad.) to clean the connection. but now im not getting everything in after de moment where earlier it stopped but just some of the data.
so close..

Prasanna Seshadri said...

Thats a good progress, keep hacking on, you will get it.


Copyright © 2008 Prasanna Seshadri, www.prasannatech.net, All Rights Reserved.
No part of the content or this site may be reproduced without prior written permission of the author.