CODEBASE.EU

tutorials

page rating :
Linux C++ socket programming

Last modified Thursday, 29th August, 2013
This tutorial will show you how to send and receive data over a TCP/IP (ipv4 or ipv6) network using Linux and C++.

Contents

1. Before you read this tutorial.
2. What is a (internet)socket?
3. Before we create a socket.
4. Connecting to a server.
5. Creating your own server.

I. Before you read this tutorial.

This tutorial focuses on socket programming using C++, Linux and the Berkely sockets API . This library is originally written for C, but in this tutorial I will use C++ where possible. If you prefer pure C++ you can take a look at the BOOST.asio (cross platform) library (which is in fact, on linux systems, a C++ wrapper for the C Berkeley sockets API). If you don't know much about TCP/IP networking I would advise you to read a little about that subject first, because I will not explain it here. I've tried to keep this tutorial short and simple. For more information you could read the MAN pages of the system calls and functions we use in this tutorial. When you've read this tutorial you should be able to create a client and a server. For compiling I used the GCC.

II. What is a (internet)socket?

An internet socket is a begin or endpoint in a tcp/ip network connection. You can see an internet socket as the entrance or exit of a tunnel. A socket translates all incoming data in to "human readable text" or translates all outgoing data into networks packets.

The purpose of sockets is simplifying the network code of your c++ application. All the user has to do is create a socket and connect it. Once your socket is connected the socket takes care of the networking part, and all you have to worry about now is sending data to, or receiving data from, the socket.

sockets drawing

A socket can be a server or a client. Before a socket can be connected to another socket and "create a tunnel" you have to specify what type of socket it will be and where it should connect to.

How to communicate with a socket?

When you have created a socket, and it is connected to another (remote)socket, communication with the sockets is easy. Communicating with a socket is done using unix file descriptors (file handlers) and its associated functions like write() and read() (for internet sockets send() and recv() are preferred). If you never worked with files in Linux in that way, don't worry. You just need to remember that when you create a socket it returns a socket descriptor. This socket descriptor is just an integer. You can see it as the "name" of, or reference to the socket. You will need this socket descriptor if you want to interact with the socket. For example the system calls send() and recv() require a socket descriptor so they know what socket to talk with.

Socket flow

III. Before we create a socket.

Before we start creating a socket, we should know what we want to do with it (will it be a client or a server?). In this tutorial I have decided we are going to build a tcp/ip client that connects to google.com and retrieve's it's homepage. Therefore we need to provide our socket with the address (google.com), the address type (ipv4), the port (webservers usually run on port 80) and the connection type (tcp/ip).

For this purpose, some time ago, some people invented a couple of data structures. The programmer had to fill these data structures with the appropriate data so the sockets could work with it. Unfortunately these structs are a bit complicated and putting data into them isn't as easy as you would expect.

After a while some smart people came along and invented a new function called getaddrinfo(). This function deals with all the complicated structs. It also uses a new struct called called addrinfo. Lucky for us this function and the struct addrinfo are all we need to create and connect a socket.
There is one other cool thing to report about this function: It's IP agnostic. This means you don't have to specify whether you want to connect to a IPv4 or IPv6 host (unlike the older structs).
This does NOT mean the other structs are useless. The other structs are still used and can be very useful if you want to do more (complicated) things with your socket code.

Show the struct addrinfo >>>.

To keep things simple just remember that we need getaddrinfo() to fill the struct addrinfo with data we need for creating and connecting our socket.

But... there is one thing you need to remember. Sometimes a host (node) translates to multiple IP addresses. Go to your terminal and type host google.com. You will see that google.com has multiple IP addresses. Some hosts have both an IPv4 and an IPv6 adress. For this reason getaddrinfo() will not just fill one addrinfo struct, it will create a struct for every address address found. These structs will be put unto a linked list, so you can browse through them easily.

Don't worry if that sounded complicated. In our example we don't bother with the other IP addresses found, we just use the first struct (and this should usually do the trick).

The function prototype looks like this :

int getaddrinfo(const char *node, const char *service,
const struct addrinfo *host_info, struct addrinfo **res);


The parameters:

node : The host you want to connect to. This can be a hostname or IP address.
service : This is the port number you want to connect to. Usually an integer, but can also be a known service name like 'http'.
host_info : Points to the addrinfo struct to fill.
res : Points to the linked list of filled addrinfo structs.
return value : The function returns 0 if all succeeded or a non-zerro error code in case of an error.


In our code we want to connect to "google.com" at port 80. Therefore our getaddrinfo() call looks like this:


 
#include <iostream>
#include <cstring>      // Needed for memset
#include <sys/socket.h> // Needed for the socket functions
#include <netdb.h>      // Needed for the socket functions

int main()
{

  int status;
  struct addrinfo host_info;       // The struct that getaddrinfo() fills up with data.
  struct addrinfo *host_info_list; // Pointer to the to the linked list of host_info's.

  // The MAN page of getaddrinfo() states "All  the other fields in the structure pointed
  // to by hints must contain either 0 or a null pointer, as appropriate." When a struct 
  // is created in C++, it will be given a block of memory. This memory is not necessary
  // empty. Therefor we use the memset function to make sure all fields are NULL.     
  memset(&host_info, 0, sizeof host_info);

  std::cout << "Setting up the structs..."  << std::endl;

  host_info.ai_family = AF_UNSPEC;     // IP version not specified. Can be both.
  host_info.ai_socktype = SOCK_STREAM; // Use SOCK_STREAM for TCP or SOCK_DGRAM for UDP.

  // Now fill up the linked list of host_info structs with google's address information.
  status = getaddrinfo("www.google.com", "80", &host_info, &host_info_list);
  // getaddrinfo returns 0 on succes, or some other value when an error occured.
  // (translated into human readable text by the gai_gai_strerror function).
  if (status != 0)  std::cout << "getaddrinfo error" << gai_strerror(status) ;
    
}    
After using getaddrinfo() probably a lot of structs where filled with interesting information. To keep it simple we will not try to get it out of there. All we are going to do is get the nessesary information out of the first struct host_info (the first address we found with getaddrinfo()) in the linked list of structs.

Enough of this,now let's do some connecting!

IV. Connecting to a server.

Now we are ready to create a socket. To create a socket we use the socket() system call :

int socket(int domain, int type, int protocol);

The parameters:

domain : The domain argument specifies a communication domain. In our case this value is AF_INET or AF_INET6 (the internet using ip4 or ip6)
type : The type of socket. In our case it is SOCK_STREAM (tcp)
protocol : The protocol to be used with the socket-type. In our case the right protocol is automatically choosen.
return value : The socket system call returns a socket descriptor. If the socket call fails, it returns -1.

If you want to translate this error number into a error description string #include <errno.h> and use the strerror(errno) function. The same is true for all the error numbers in the system calls below.

Our socket call :

std::cout << "Creating a socket..."  << std::endl;
int socketfd ; // The socket descripter
socketfd = socket(host_info_list->ai_family, host_info_list->ai_socktype, 
host_info_list->ai_protocol);
if (socketfd == -1)  std::cout << "socket error " ;
As you can see above, we use the values stored in the first struct host_info of the linked list getaddrinfo() we created. Note: there might be more addresses in the linked list but we just keep it simple and use the first one.

We are now ready to connect to google.com. For that we use the connect() system call:

int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

The parameters:

sockfd : the socket descriptor the socket() call returns.
addr : The address we need to connect to. In our case stored in 'host_info_list->ai_addr'.
addrlen : The addrlen argument specifies the size of addr. In our case stored in 'host_info_list->ai_addrlen'.
return value : If the connection succeeds, zero is returned. On error, -1 is returned, and errno is set appropriately.

Resulting in our connection call looking like this :

std::cout << "Connect()ing..."  << std::endl;
status = connect(socketfd, host_info_list->ai_addr, host_info_list->ai_addrlen);
if (status == -1)  std::cout << "connect error" ;

If we didn't get an error by now we should be connected to google.com at port 80. The next thing we would like to do is send and receive some data!

Sending and recieving data.

For sending an recieving data we use the send() and recv() system calls. The send() call :

ssize_t send(int sockfd, const void *buf, size_t len, int flags);

The parameters:

sockfd : The socket descriptor the socket() call returns.
buf : The message we want to send.
len : The lenght of this message. Equals strlen(buf).
flags : Without this parameter, this call would be the same as the write() call. This parameter gives you some extra options. Read the send() MAN page for more information.
return value : On success, this call returns the number of characters sent. On error, -1 is returned, and errno is set appropriately. If you want to know if your message was send, this value should be the same as strlen(buf)

In our case we want to get the homepage of google.com, so we will pretent to be a browser (in fact, we are, just a very simple one), so we comply to the HTTP protocol and request the homepage. We add the following code :

std::cout << "send()ing message..."  << std::endl;
char *msg = "GET / HTTP/1.1\nhost: www.google.com\n\n";
int len;
ssize_t bytes_sent;
len = strlen(msg);
bytes_sent = send(socketfd, msg, len, 0);

The last system call we have to use here is recv(). If the other socket (in this case google's server) sends data back to us, our socket will store this in a buffer. This buffer can be read using the recv() call.

The recv() system call :

ssize_t recv(int sockfd, void *buf, size_t len, int flags);

The parameters:

sockfd : The socket descriptor the socket() call returns.
buf : The variable we want to store the data in (input buffer).
len : The amout of data it will read from the input buffer.
flags : Read the recv() MAN page for more information.
return value : This calls returns the number of bytes received, or -1 if an error occurred. The return value will be 0 when the peer has performed an orderly shutdown.
If no messages are available at the socket, the recv() call halts execution of your code and waits for a message to arrive. This behaviour is called "blocking". By default a socket is in blocking mode. A socket can also be in "non-blocking" mode so it will just continue your code if there is no data in the buffer.

One of the last pieces of code we need is:


std::cout << "Waiting to recieve data..."  << std::endl;
ssize_t bytes_recieved;
char incoming_data_buffer[1000];
bytes_recieved = recv(socketfd, incoming_data_buffer,1000, 0);
// If no data arrives, the program will just wait here until some data arrives.
if (bytes_recieved == 0) std::cout << "host shut down." << std::endl ;
if (bytes_recieved == -1)std::cout << "recieve error!" << std::endl ;
std::cout << bytes_recieved << " bytes recieved :" << std::endl ;
std::cout << incoming_data_buffer << std::endl;

recv() does NOT know when google is done sending data, so we just have to create our own method. This example only reads the first 1000 bytes bytes send by google. When we want to read the rest, we could make a loop. The problem with this solution would be that at some point there is no more data in the buffer, and recv() keeps waiting for ever. The solution : Non-blocking sockets or multithreading.

Other system calls you should know about.

A function asociated with getaddrinfo() is freeaddrinfo(). You should use this function if you no longer need the linked list of addrinfo structs. This function frees the memory used by the linked list. When you're done using your socket, you can close it using the close() system call. Finally we add to our code :

std::cout << "Receiving complete. Closing socket..." << std::endl;
freeaddrinfo(host_info_list);
close(socketfd);


Download code

The result is a program that connects to google and downloads (the first 1000 bytes of) the google homepage. You can download it HERE .
Compile it on linux with gcc : g++ tcpclient.cpp -o client

V. Creating your own server.

Creating a server is almost similar as creating a client. The difference is that we replace the connect() call by 3 other calls : bind(), listen() and accept().

The getaddrinfo() function also needs different parameters, because now we want our socket to be a server on our own host using our own port.
What we do is simply change "google.com" to NULL (NULL will automatically use your localhost) and "80" to 5555 (the port number we want to listen on).
In addition we add one extra line to specify that we want to accept connections on any of the addresses of the local host.
Note: Unless you are running your code as root, do NOT use a port number lower then 1024, because port numbers lower then 1024 are usually reserved for your OS.


host_info.ai_flags = AI_PASSIVE; 
status = getaddrinfo(NULL, "5555", &host_info, &host_info_list);

Now we create a socket just like we did in our client code...

Instead of connect() we use bind() to bind the socket to the local port we specified. We use this call so Linux will know that is has to forward an incoming packet on the specified port to your program's socket descriptor.

The bind() call :

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

The parameters:

sockfd : The socket descriptor the socket() call returns.
addr : The address we want to listen on (localhost).
addrlen : The lenght of this address.
Return value : Like all the other calls it also returns an integer. If it's '0' the call succeeded, if it's -1, we got an error that will be stored in errno as usual.
Our bind() call ends up looking like this :

std::cout << "Binding socket..."  << std::endl;
// we make use of the setsockopt() function to make sure the port is not in use.
// by a previous execution of our code. (see man page for more information)
int yes = 1;
status = setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
status = bind(socketfd, host_info_list->ai_addr, host_info_list->ai_addrlen);
if (status == -1)  std::cout << "bind error" << std::endl ;


The bind call doesn't make your server listen for incoming connections yet. Why not? Because we can also use the bind() call in our client code. Say for example we wanted our client program to use localport 9999 , we would place a bind call before the connect() call. If you leave it out, your OS will choose any available port.

What next?

What we need to do next is tell Linux we are actually listening for incoming connections on that port. We do this using the listen() call:

The listen() call:

int listen(int sockfd, int backlog);

The parameters:

sockfd : The socket descriptor the socket() call returns.
backlog : Our server can only handle 1 client at a time. What if more clients want to connect to your server at the same time? With backlog you can specify how many connections will be put in que. For example, if you set it to 5, and 7 connections to your server are made, 1 will fail, 1 will connect and the other 5 will be put "on hold".
Return value : As usual it returns -1 on error and 0 on success.

Our listen call :

std::cout << "Listen()ing for connections..."  << std::endl;
status =  listen(socketfd, 5);
if (status == -1)  std::cout << "listen error" << std::endl ;

Now some client decides to connect to your server, what do we do?
We accept() the client. But this call does something special. It returns a new socket descriptor. Why?
Because we are a server and we want to serve as many people as possible, right?
Therefore accept() creates a new socket for each client that connects. This way we can talk to to our client on a "private" socket and keep our old socket listening for new visitors.

The accept() call :

new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &addr_size);

Parameters :

sockfd : The socket descriptor the socket() call returns.
their_addr : their_addr will usually be a pointer to a local struct sockaddr_storage. This is where the information about the incoming connection will be stored (Like the client's IP address and port).
addr_size : addr_size is the size of the their_addr struct.

return value : A brand new socket descriptor on success! Or -1 on error.

our accept call :

std::cout << "Listen()ing for connections..."  << std::endl;
status =  listen(socketfd, 5);
if (status == -1)  std::cout << "listen error" << std::endl ;


At this time the connection should be established and we are ready to talk using our new socket descriptor. Like in the client, we do this with the send() and recv() calls. But DO NOT FORGET to use the new socket descriptor in the send() and recv() calls returned by accept()!

Finally we use the freeaddrinfo() and close() functions because we like clean and proper code.

Download

Download the complete server example HERE .
Testing : To test your server you can just telnet into it (telnet 127.0.0.1 5555) or just use the client we created before (just change "google.com" to "127.0.0.1" and "80" to "5555").

What about serving multiple clients at the same time like webservers do?

You can. However this is a little bit more complicated. There are multiple methods for this, one of the most popular ones is multithreading. You can read about multithreading in my Multithreading tutorial, or you can take a look at my Multithreaded chess/chat server

Comments




Yourname [ Saturday 2nd of August 2014 07:08:51 AM ]

Your message...




Ali [ Wednesday 9th of July 2014 06:05:14 PM ]

Hey author. Can you provide a tutorial on windows sockets too if you have time ?




Ali [ Wednesday 9th of July 2014 06:03:08 PM ]

Nice tutorial :)


include #include < unistd.h > for close() functions if they dont work.

The rest awesomely done.

Good job.




Yourname [ Wednesday 9th of July 2014 08:54:16 AM ]

sorry but there were is no any header file is include in my tc 

#include <sys/socket.h> 
#include <netdb.h>




Moose [ Monday 9th of June 2014 10:33:34 PM ]

Wonderfully done and incredibly helpful! It provides complete and thorough explanations while remaining concise.




Yourname [ Friday 23rd of May 2014 09:41:32 AM ]

Your message...




asdadasd [ Tuesday 20th of May 2014 09:29:40 AM ]

sadada




swaaws [ Saturday 3rd of May 2014 12:18:20 PM ]

Thanks.. too

change

char *msg = \"GET / HTTP/1.1\\nhost: www.google.com\\n\\n\";

to

#define msg  \"GET / HTTP/1.1\\nHost: www.google.de\\n\\n\"

execute code in comment ????? security fail




swaaws [ Saturday 3rd of May 2014 11:26:39 AM ]

Thanks....


@Welgriv: CHANGE

close(socketfd);
to ...
int close(socketfd);


dont add any .h, its simple, socketfd is an int, what will you close ... the socketfd. then close the socketfd with int close(socketfd);




Yourname [ Saturday 26th of April 2014 11:02:07 AM ]

Your message...




Yourname [ Saturday 26th of April 2014 11:01:57 AM ]

Your message...




mak [ Thursday 24th of April 2014 05:50:11 PM ]

nice turorial for the beginners in socket like me....Thanks.!




Viru [ Thursday 3rd of April 2014 08:37:48 AM ]

Great and simple way to explain complex things. Thanks a lot for all the effort and time you have given to this.




dilee [ Friday 7th of March 2014 08:13:06 PM ]

nice work man.....thankx




Vonflavison [ Tuesday 18th of February 2014 11:01:17 AM ]

U\'ve being a wonderful teacher from the beginning to the end throughout this lecture. Good presentation of concepts. Thank u 




Welgriv [ Wednesday 12th of February 2014 12:45:01 PM ]

close() functions dosen\'t work for me, it seems like they don\'t exist in the headers...




shauryachats [ Tuesday 11th of February 2014 06:02:10 PM ]

Thank you very much for the wonderful tutorial.

Hope we get more in the future. :)




Codeword [ Wednesday 5th of February 2014 11:02:26 AM ]

Thank you very much for the guide. Vary detailed and simple! Just the way I wanted




Yourname [ Tuesday 4th of February 2014 10:59:13 AM ]

Your message...




voip [ Thursday 16th of January 2014 07:55:44 AM ]

plz give the concrete output of TCPCLIENT and TCPSERVER code that you have given.....




Matt [ Thursday 9th of January 2014 05:33:24 AM ]

The last code block is a repeat of listen(), and isn\'t accept(), like you intended. ;) Thank you for the full code example though so we can still learn it! This has been a great guide.




sandman [ Tuesday 31st of December 2013 07:59:31 AM ]

Great




samansabuhi [ Friday 27th of December 2013 09:32:04 PM ]

thank\'s a lot. your code is perfect.

but in IV. Connecting to a server code you most include <unistd.h> becausse close() function at last part of the code didn\'t work.
I had to do my assignment and your code help me a lot.

I have this warning
warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]

and change 
char *msg = \"GET / HTTP/1.1\\nhost: www.google.com\\n\\n\";
to
string msg = \"GET / HTTP/1.1\\nhost: www.google.com\\n\\n\";

then use .c_str() function to convert them to char *

thank\'s again.




Yourname [ Tuesday 24th of December 2013 02:39:21 PM ]

Your message...




pallavi [ Monday 23rd of December 2013 12:01:51 PM ]

i didnt get it :P




MircooV [ Saturday 7th of December 2013 10:55:04 PM ]

I noticed that it\'s hard to find your blog in google, i found it on 24th spot, you should get some quality backlinks to rank it in google and increase traffic. I had the same problem with my blog, your should search in google for - insane google ranking boost - it helped me a lot




GP [ Friday 6th of December 2013 02:35:54 AM ]

Thanks




georges [ Thursday 21st of November 2013 04:52:42 PM ]

great! thanks!


just have to \"#include <unistd.h>\" for \"close(socketfd)\"




Yourname [ Wednesday 20th of November 2013 08:28:46 PM ]

Nice tutorial understood well 




habesh [ Monday 18th of November 2013 04:01:25 PM ]

nice tutorial thanks,




pap [ Tuesday 12th of November 2013 01:46:38 PM ]

test





Yourname [ Sunday 10th of November 2013 12:25:40 PM ]

Your message...




Aaron [ Sunday 10th of November 2013 10:12:03 AM ]

You have not even defined the below structure in program, how does getaddrinfo comes to know that I have to fill these data like ai_flags, ai_family?:

struct addrinfo {
    int              ai_flags;     // This  field  specifies additional options.
    int              ai_family;    // IPv4, IPv6 or IP agnostic.
    int              ai_socktype;  // TCP or UDP.
    int              ai_protocol;  // The protocol for the returned socket addresses.
    size_t           ai_addrlen;   // Size of ai_addr in bytes
    struct sockaddr *ai_addr;      // Containing the IP address and port.
    char            *ai_canonname; // The Canonical hostname.

    struct addrinfo *ai_next;      // linked list, next address.
};




Nono [ Saturday 9th of November 2013 01:10:06 PM ]

Excellent !




Yourname [ Friday 20th of September 2013 08:46:14 AM ]

Your message...




asha [ Wednesday 11th of September 2013 06:00:38 AM ]

Thank you author!! Good tutorial..




ktsiesao [ Tuesday 10th of September 2013 11:48:08 AM ]

製品の色、肌ケアの靴は最新の LV の労働者は心配に対処するように設計されている自然な手段デザインによってその期間を意識した設計で従事している物事のほんの一握りだけでなくインテリア ・ ファッション靴の彼らの選択の安心を優先するように見える人に加えてオンワード群衆これらの企業は、各 LV 概念の背後にある紙の心の最低は長い時間を持続させる芸術の靴を設計最高のデザイナー服このは、サーチャー欲望の運のベストを生成することをあなたに参加する各 1 つの収集であなたの服装をほめるあなたのすべての部分を常に見つけることができますこの方法ブランドを導入、完璧な最新をしみ出させるまたは人々 を取る許可 LV セット品質の靴を取得するリアルタイム外観を着用するかどうかを定義する検索なし、訴訟一目人




sanket [ Tuesday 27th of August 2013 11:22:40 PM ]

just complete fucking awesome!

(i\'m noob! :) )




Anon [ Wednesday 21st of August 2013 03:03:49 PM ]

Great tutorial.




nallanaharish [ Thursday 8th of August 2013 07:04:57 AM ]

not that much good




Andrew [ Tuesday 6th of August 2013 11:00:52 PM ]

Its amazing...... i try understand socket using several days. With this tutorial, i make it for 20 minutes ) Thank Author !!!




rocksean30 [ Monday 5th of August 2013 06:54:20 AM ]

To compile on solaris

tcpclient.cpp
 g++ tcpclient.cpp -o tcpclient -lnsl -lsocket -lresolv

tcpserver.cpp
  g++ tcpserver.cpp -o tcpserver -lnsl -lsocket -lresolv




omaycotte [ Thursday 1st of August 2013 04:17:47 AM ]

The simplest & cleanest tutorial on sockets I ever seen. Nice job




nafiseb [ Thursday 25th of July 2013 05:27:34 PM ]

Thanks so much! It was such a nice tutorial :)




ABC [ Wednesday 17th of July 2013 12:10:34 PM ]

nice tutorial




KrishnaKumar [ Sunday 30th of June 2013 02:57:22 PM ]

Thank you. I could make it work on my Raspberry pi.




Harsha [ Monday 24th of June 2013 05:56:04 AM ]

Hi guys I followed the above code and i built server and client,but iam getting connection failed error.could you please help me in this issue and also tell me prcedure to run the program.Thank you




Raj [ Wednesday 19th of June 2013 02:15:41 PM ]

This is a very good tutorial. Thanks for your wonderful presentation.. 




KrishnaKumar [ Sunday 16th of June 2013 11:11:40 AM ]

A nicely presented easy to understand tutorial.




luis [ Monday 13th of May 2013 09:54:42 PM ]

thank you





BishalNepali [ Monday 6th of May 2013 06:46:59 PM ]

After I nearly gave up trying to learn sockets I ended up to this post.

 You really know how to teach. Thanks Dude. BTW, Wheres the donation Button?




Anish [ Monday 29th of April 2013 08:09:37 PM ]

I connected two Laps using a LAN Cable . I am able to Ping them both. But am not able to send or receive data using this program. The Server Code stops itself showing a bind error and the client stops itself after the call of the send function. Anybody can help me out. 


P.S : I am just a beginner in networking. A college student.




Dhivya [ Thursday 25th of April 2013 07:35:05 AM ]

Informative !!!




Wilson [ Wednesday 20th of March 2013 11:22:17 PM ]

Thank you so much... you should add a donation button because I would have donated to you! 

People like you make the internetz a nice place!




pratik [ Saturday 9th of March 2013 02:44:08 PM ]

thank you. 




bravo2zero [ Sunday 24th of February 2013 05:42:36 AM ]

Nice tutorial / Its about time some one put together something this nice .How ever i think it would be nice to add packet creation and data loading just to complete the socket guide .




Digin [ Friday 18th of January 2013 11:23:51 AM ]

see this link for a sample code

http://godlytalias.blogspot.in/2013/01/socket-programming-in-c-with-multiple.html




gurug [ Friday 14th of December 2012 09:00:15 PM ]

good one




SK [ Thursday 6th of December 2012 05:51:40 PM ]

I want receive stream of data from memory using internet socket on TCP server.


Data size is 100 MBytes, is it possible to get chunk of data in 1 MBytes?

Help !




Pankaj [ Thursday 22nd of November 2012 10:33:24 AM ]

getting error \"Connection refused\" on

status = connect(socketfd, host_info_list->ai_addr, host_info_list->ai_addrlen)

Please reply at pankajworld@yahoo.com




JG [ Saturday 27th of October 2012 02:11:06 PM ]

Great tutorial! Thank you, well explained and easy to understand for beginners!




vabbz [ Wednesday 12th of September 2012 08:38:35 AM ]

thank u :)




simon [ Thursday 12th of July 2012 11:02:00 AM ]

Well-balanced and complete tutorial.

It helps, thank you.




kino [ Sunday 1st of April 2012 03:18:09 AM ]

making the big switch from windoze to Debian Linux....with your tut. got the sockets working....Thanks




arnold [ Wednesday 20th of July 2011 10:09:07 PM ]

good tutorial. thank you.