Introduction
The WinSock (Windows Sockets) API is a socket programming library for
Microsoft Windows Operating Systems. It was originally based on Berkeley
sockets. But several Microsoft specific changes were employed. In this article I
shall attempt to introduce you to socket programming using WinSock, assuming
that you have never done any kind of network programming on any Operating
System.
If you only have a single machine, then don't worry. You can still program
WinSock. You can use the local loop-back address called localhost with the IP
address 127.0.0.1. Thus if you have a TCP server running on your machine, a
client program running on the same machine can connect to the server using this
loop-back address.
Simple TCP Server
In this article I introduce you to WinSock through a simple TCP server, which
we shall create step by step. But before we begin, there are a few things that
you must do, so that we are truly ready for starting our WinSock program
- Initially use the VC++ 6.0 App Wizard to create a Win32 console
application.
- Remember to set the option to add support for MFC
- Open the file stdafx.h and add the following line :-
#include <winsock2.h>
- Also
#include
conio.h and iostream just after
winsock2.h
- Take Project-Settings-Link and add ws2_32.lib to the library modules list.
The main function
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
cout << "Press ESCAPE to terminate program\r\n";
AfxBeginThread(ServerThread,0);
while(_getch()!=27);
return nRetCode;
}
What we do in our main()
is to start a thread and then loop a call to
_getch()
.
_getch()
simply waits till a key is pressed and returns the ASCII value of the
character read. We loop till a value of 27 is returned, since 27 is the ASCII
code for the ESCAPE key. You might be wondering that even if we press ESCAPE,
the thread we started would still be active. Don't worry about that at all. When
main()
returns the process will terminate and the threads started by our main
thread will also be abruptly terminated.
The ServerThread function
What I will do now is to list our ServerThread
function and use code comments
to explain what each relevant line of code does. Basically what our TCP server
does is this. It listens on port 20248, which also happens to be my Code Project
membership ID. Talk about coincidences. When a client connects, the server will
send back a message to the client giving it's IP address and then close the
connection and go back to accepting connections on port 20248. It will also
print a line on the console where it's running that there was a connection from
this particular IP address. All in all, an absolutely useless program, you might
be thinking. In fact some of you might even think this is as useless as SNDREC32.EXE
which comes with Windows. Cruel of those people I say.
UINT ServerThread(LPVOID pParam)
{
cout << "Starting up TCP server\r\n";
SOCKET server;
WSADATA wsaData;
sockaddr_in local;
int wsaret=WSAStartup(0x101,&wsaData);
if(wsaret!=0)
{
return 0;
}
local.sin_family=AF_INET;
local.sin_addr.s_addr=INADDR_ANY;
local.sin_port=htons((u_short)20248);
server=socket(AF_INET,SOCK_STREAM,0);
if(server==INVALID_SOCKET)
{
return 0;
}
if(bind(server,(sockaddr*)&local,sizeof(local))!=0)
{
return 0;
}
if(listen(server,10)!=0)
{
return 0;
}
SOCKET client;
sockaddr_in from;
int fromlen=sizeof(from);
while(true)
{
char temp[512];
client=accept(server,
(struct sockaddr*)&from,&fromlen);
sprintf(temp,"Your IP is %s\r\n",inet_ntoa(from.sin_addr));
send(client,temp,strlen(temp),0);
cout << "Connection from " << inet_ntoa(from.sin_addr) <<"\r\n";
closesocket(client);
}
closesocket(server);
WSACleanup();
return 0;
}
Testing it out
Run the server and use telnet to connect to port 20248 of the machine where
the server is running. If you have it on the same machine connect to localhost.
Sample Output
We see this output on the server
E:\work\Server\Debug>server
Press ESCAPE to terminate program
Starting up TCP server
Connection from 203.200.100.122
Connection from 127.0.0.1
E:\work\Server\Debug>
And this is what the client gets
nish@sumida:~$ telnet 202.89.211.88 20248
Trying 202.89.211.88...
Connected to 202.89.211.88.
Escape character is '^]'.
Your IP is 203.200.100.122
Connection closed by foreign host.
nish@sumida:~$
Conclusion
Well, in this article you learned how to create a simple TCP server. In
further articles I'll show you more stuff you can do with WinSock including
creating a proper TCP client among other things. If anyone has problems with
compiling the code, mail me and I shall send you a zipped project. Thank you.