# C/C++ Sockets FAQ and How-To Win+Linux



## Oliver_FF (Apr 3, 2008)

Ok so many many programs these days make use of networking and the internet. Ever wondered how simple it would be to connect two programs together over such? Wonder no further  

*What are sockets?*
Well sockets are used as an interface to access a network through your operating system. Imagine your system to be contained inside of a locked room, with the only point of entry being a wall totally plastered in wall plugs. You create a socket, bind it to the plug and you've got access outside on the network. Also whilst we're at it, you can think of your firewall as a dude that stands about watching the wall plugs, pulling out ones that it doesn't like XD


*Getting Started*
Ok first you'll need to include the appropriate header files for sockets.
Windows

```
#include <winsock.h>
```
Pass this to GCC: /lib/libws2_32.a
winsock as in Windows Socket 
Linux

```
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
```
Pass these to GCC: -lsocket -lnsl
The headers for Unix are split up more so you don't get the overhead of a huge amount of stuff you just don't need!

Extra stuff for Windows...
You'll need a load of extra stuff for Windows:

```
WSADATA wsaData;
WSAStartup(0x0202, &wsaData);
```
The first line is a data structure that holds data about the current winsock version. The second line initialises the winsock component so you can use it. MISS THESE LINES AND NONE OF THIS WILL WORK  

Creating your first socket
First you need to define some information about the type of connection you want to establish. Here i'm after a two-way socket (SOCK_STREAM) that uses IPv4 (AF_INET) and uses TCP (IPPROTO_TCP) for reliable data transfer. Thankfully both ways are interoperable between OS's 

```
int thisSocket;
	struct sockaddr_in destination;

	destination.sin_family = AF_INET;
	thisSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 
	if (thisSocket < 0)
	{
		printf("\nSocket Creation FAILED!");
		return 0;
	}
```

Closing your first socket 
The differences here come from the way both OS's handle networking...
Windows

```
closesocket(thisSocket)
	WSACleanup();
```
Linux

```
close(thisSocket)
```


*Hosting a connection with your socket*
There are three stages to host and establish a connection:

Bind the socket. Going back to this wall covered in wall plugs, this is where you take your socket and stick it into a plug.
Listen on the socket. This is where you sit and wait for someone on the outside world to try to connect to your socket.
Accept a connection. This is where you welcome them in and start talking.

Binding to a socket
Before you can bind to a socket you want to know what port you want to listen on. In this example i'll be listening on port "13374" because it's 1337-er than the others 
The htons(int) function basically converts a port number to the type that sockets prefer.

```
destination.sin_port = htons (13374);
	destination.sin_addr.s_addr = INADDR_ANY;
	if (bind(thisSocket, (struct sockaddr *)&destination, sizeof(destination))<0){
		printf("\nBinding Socket FAILED!\n");
		if (thisSocket) close(thisSocket);
		return 0;
	}
```

Listening on a socket
This function will *BLOCK* until someone tries to connect , so if your program hangs on this line and you're wondering why, it's because nobodies connected yet. The 5 refers to how many people can be trying to connect at once, not entirely sure about it tbh.

```
printf("\nListening on 13374...");
	if (listen(thisSocket, 5)<0){
		printf("\nListening on Socket FAILED!\n");
		if (thisSocket) close(thisSocket);
		return 0;
	}
```

Accepting a connection
The last stage . You'll need an object to get information about who you are connecting to, whose information you can read out of the struct to find out more about them after the function returns.

```
struct sockaddr_in clientAddress;
	int clientSize = sizeof(clientAddress);
	thisSocket= accept(thisSocket, (struct sockaddr *)&clientAddress, (int *) &clientSize);
	if (thisSocket<0)
	{
		printf("\nSocket Connection FAILED!\n");
		if (thisSocket) close(thisSocket);
		return 0;
	}
	printf("\nConnection Established!");
```


*Connecting to a host*
Thankfully connecting to a host is blissfully simple  This will be connecting to port 13374, the same port that we should be listening on above and it'll connect to the local host (aka you) so you can try this stuff out 

```
destination.sin_port = htons(13374);
	destination.sin_addr.s_addr = inet_addr("127.0.0.1");
	if (connect(thisSocket,(struct sockaddr *)&destination,sizeof(destination))!=0){
		printf("\nSocket Connection FAILED!\n");
		if (thisSocket) close(thisSocket);
		return 0;
	}
	printf("\nConnected!");
```


*Sending data over a socket*
So you've got a socket set up at last, how do you send data over it?
The send() function takes the following:

The socket you want to send data over.
A char array containing your data you want to send.
An int containing the amount of data in the buffer.
An offset in the buffer incase you only want to send a part of it. 0 means start from the beginning.


```
send(thisSocket, buffer, BUFFERSIZE, 0);
```


*Receiving data over a socket*
The revc() function takes the following:

The socket you want to recieve data from.
A char array you want to store the data in.
The maximum size of the above array.
An offset in the buffer incase. 0 starts from the beginning.
The function returns the number of bytes that were received, up to the maximum you speficied.
WARNING - this function *BLOCKS* until data arrives.


```
int newData;
	newData = recv(thisSocket, buffer, BUFFERSIZE, 0);
```


*My ways for writing for both Windows and Unix*
At the top of every file I start with two lines:

```
#define __WINDOWS
#define __LINUX
```
and comment out which ever one i'm not using at the time.

This lets me do things like this:

```
#ifdef __WINDOWS
#include <winsock.h>
#endif
#ifdef __LINUX
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
void closesocket(int socket) { close(socket); }
#endif
```
and

```
#ifdef __WINDOWS
	WSADATA wsaData;
#endif
```
and

```
#ifdef __WINDOWS
	WSAStartup(0x0202, &wsaData);
#endif
```
and

```
#ifdef __WINDOWS
    WSACleanup();
#endif
```

Notice how Linux makes it way easier to do networking


----------



## Kreij (Apr 3, 2008)

Great post !!!!

The last time I did any socket programming was when I was using Unix machines.
That was about 15 years ago.
Brings back memories. Not necessarily fond memories, but memories.

Keep 'em coming Oliver_FF ... we need to boost the P&W  section !!!

PS. I see you've mastered the [code] tags


----------



## Oliver_FF (Jun 1, 2008)

Bump for the follow-up http://forums.techpowerup.com/showthread.php?p=818797


----------



## lo0ney (Jan 14, 2009)

Thanks alot!


----------

