| d_arin100 |
14Oct2009 17:54 |
Making client and server using win32 socket.
Introduction
Socket is an interface between an application process and transport layer. The application process can send or receive messages to/from another application process (local or Network) through a socket. Winsock is the lowest level Windows API for TCP/IP programming. Part of the code is located in winsock.dll and the rest is inside the Windows kernel. In this article I shall try to explain how we can create a server and a client using winsock.
Background
Before going to the main topic I am trying to explain where the socket exists in different network layer.
Code:
Server Client
---------------------- ----------------------
| Application layer | | Application layer |
User Space | | User Space | |
+--------------------+ +--------------------+
| Socket | | Socket |
| | | |
+--------------------+ +--------------------+
| Transport layer | | Transport layer |
| | | |
| | | | | | | |
| | | |
Kernel Space | Network layer | Kernel Space | Network layer |
| | | |
| | | | | | | |
| | | |
| Link layer | | Link layer |
| | | |
| | | | | | | |
| | | |
| Physical layer | | Physical layer |
---------------------- ----------------------
Now I am trying to explain the protocol of client and server and the function needs
to call for making this client server connection.
Code:
Server Client
----------------- -----------------
| WSAStartup() | | WSAStartup() |
+---------------+ +---------------+
| | | |
+---------------+ +---------------+
| socket() | | socket() |
+---------------+ +---------------+
| | | |
+---------------+ | |
| bind() | | |
+---------------+ | |
| | | |
+---------------+ +---------------+
| listen() | <----------- | connect() |
+---------------+ +---------------+
| | | |
+---------------+ | |
| accept() | | |
+---------------+ | |
| | | |
+---------------+ +---------------+
| send() | -----------> | recv() |
| | | |
| recv() | <----------- | send() |
+---------------+ +---------------+
| | | |
+---------------+ +---------------+
| closesocket() | | closesocket() |
+---------------+ +---------------+
| | | |
+---------------+ +---------------+
| WSACleanup() | | WSACleanup() |
----------------- -----------------
The WSAStartup() function initializes the Winsock.dll.
The socket() function creates a socket.
The bind() function bind a previously created socket to a specified socket address.
listen() begin listening on the port specified by the previous b ind() call.
Server program call accept() immediately after calling Listen(). a ccept() returns when a client connects to the socket, sending back a new socket that corresponds to the new connection.
The client program calls connect() after c reating socket. Connect returns when the connection has been made.
The send() and recv() are for sending/receiving data to/from socket.
The closesocket() function closes an existing socket.
WSACleanup() terminates to use of socket dll.
The following code will create a server which will communicate with clients.
The code
Code:
#include <stdio.h>
#include <windows.h>
#include <winsock.h>
#define SOCKET_OK 0
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nShow)
{
WORD sockVer;
WSADATA wsaData;
int retVal;
sockVer = MAKEWORD(2,2);
WSAStartup(sockVer, &wsaData);
/// Creating socket
SOCKET servSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if(servSock == INVALID_SOCKET)
{
MessageBox(NULL, "Unable to create socket()", "SOCKET ERROR", MB_OK);
WSACleanup();
return SOCKET_ERROR;
}
/// Filling in sockaddr_in struct
SOCKADDR_IN sin;
sin.sin_family = PF_INET;
sin.sin_port = htons(1111);
sin.sin_addr.s_addr = INADDR_ANY;
retVal = bind(servSock, (LPSOCKADDR)&sin, sizeof(sin));
if(retVal == SOCKET_ERROR)
{
MessageBox(NULL, "Unable to bind", "SOCKET ERROR", MB_OK);
WSACleanup();
return SOCKET_ERROR;
}
/// Trying to listen socket
retVal = listen(servSock, 10);
if(retVal == SOCKET_ERROR)
{
MessageBox(NULL, "Unable to listen()", "SOCKET ERROR", MB_OK);
WSACleanup();
return SOCKET_ERROR;
}
/// Waiting for a client
SOCKET clientSock;
clientSock = accept(servSock, NULL, NULL);
if(clientSock == INVALID_SOCKET)
{
MessageBox(NULL, "Unable to accept()", "SOCKET ERROR", MB_OK);
WSACleanup();
return SOCKET_ERROR;
}
char szReq[8];
retVal = recv(clientSock, szReq, 8, 0);
if(retVal == SOCKET_ERROR)
{
MessageBox(NULL, "Unable to recv()", "SOCKET ERROR", MB_OK);
return SOCKET_ERROR;
}
MessageBox(NULL, szReq, "Got the request from client", MB_OK);
char *szResp = "Response";
MessageBox(NULL, szResp, "Sending response from server", MB_OK);
retVal = send(clientSock, szResp, strlen(szResp), 0);
if(retVal == SOCKET_ERROR)
{
MessageBox(NULL, "Unable to send()", "SOCKET ERROR", MB_OK);
return SOCKET_ERROR;
}
/// Closing socket
closesocket(clientSock);
closesocket(servSock);
WSACleanup();
return SOCKET_OK;
}
Making a client application which will send/ receive data from the server.
Code: Cpp
#include <windows.h> #include <winsock.h> int WINAPI WinMain(HINSTANCE hHinst, HINSTANCE hPrevHinst, LPSTR lpCmdLine, int nShow) { WORD ver = MAKEWORD(2,2); WSADATA wsaData; int retVal=0; WSAStartup(ver,(LPWSADATA)&wsaData); LPHOSTENT hostEnt; /// Collect information of the server hostEnt = gethostbyname("Myxp"); if(!hostEnt) { MessageBox(NULL, "Unable to collect gethostbyname()", "ERROR", MB_OK); WSACleanup(); return 1; } /// Creating a socket SOCKET clientSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if(clientSock == SOCKET_ERROR) { MessageBox(NULL, "Unable to create socket", "ERROR", MB_OK); WSACleanup(); return 1; } SOCKADDR_IN serverInfo; serverInfo.sin_family = PF_INET; serverInfo.sin_addr = *((LPIN_ADDR)*hostEnt->h_addr_list); serverInfo.sin_port = htons(1111); retVal=connect(clientSock,(LPSOCKADDR)&serverInfo, sizeof(serverInfo)); if(retVal==SOCKET_ERROR) { MessageBox(NULL, "Unable to connect()", "ERROR", MB_OK); WSACleanup(); return 1; } MessageBox(NULL, "Connection made sucessfully", "SUCCESS", MB_OK); char *pBuf = "Request"; MessageBox(NULL, "Sending request from client", "SENDING....", MB_OK); retVal = send(clientSock, pBuf, strlen(pBuf), 0); if(retVal == SOCKET_ERROR) { MessageBox(NULL, "Unable to send()", "ERROR", MB_OK); WSACleanup(); return 1; } char szResponse[9]; retVal = recv(clientSock, szResponse, 9, 0); if(retVal == SOCKET_ERROR) { MessageBox(NULL, "Unable to recv()", "SOCKET ERROR", MB_OK); WSACleanup(); return 1; } MessageBox(NULL, szResponse, "Got the response from server", MB_OK); closesocket(clientSock); WSACleanup(); return 0; }
|