![]() |
General Programming »
Internet / Network »
Beginners
Beginner
Beginning Winsock Programming - Simple TCP clientBy Nishant SivakumarA simple TCP client is explained. |
VC6Win2K, MFC, Dev
|
|
Advanced Search |
|
|
|
||||||||||||||||

This is a sequel to the article Beginning Winsock Programming - Simple TCP server and if you have not read that already I would recommend that you do that first. In this article I'll show how you can write a simple TCP client program. We'll write a program that will connect to an HTTP server and retrieve a file.
WSAStartup()socket()gethostbyname()/gethostbyaddr()connect()send()/recv() till our tcp chat is overclosesocket()WSACleanup()As with every other WinSock program we need to initialize the WinSock library. Basically it is also a kind of check to see if WinSock is available on the system in the precise version we expect it to be.
int wsaret=WSAStartup(0x101,&wsaData); if(wsaret) return;
The socket is the entity that acts as the endpoint between the client and the
server. When a client is connected to a server, there are two sockets. The
socket at the client side and the corresponding socket at the server side. Lets
call them CLIENTSOCK and SERVERSOCK. When the client uses send() on CLIENTSOCK
the server can use recv() on the SERVERSOCK to receive what the client sends.
Similarly the reverse is also true. For our purposes we create the socket using a
function called socket().
SOCKET conn; conn=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); if(conn==INVALID_SOCKET) return;
Obviously we need to get info about the host [the server] before we can
connect to it. There are two functions we can use - gethostbyname() and gethostbyaddr(). The
gethostbyname() function is used when we have the DNS name
of our server, something like codeproject.com or ftp.myserver.org. The
gethostbyaddr() function is used when we actually have the IP address of the
server to connect to, something like 192.168.1.1 or 202.54.1.100.
Obviously we would want to give our end user the option of entering either a
DNS name or an IP address. Thus for making that part of it transparent to him,
we do a little trick as shown below. We use the function inet_addr() on the
entered string. The inet_addr() function converts an IP address into a standard
network address format. Thus if it returns failure, we now know that the string
cannot be an IP address, if it succeeds we assume that it was a valid IP
address.
if(inet_addr(servername)==INADDR_NONE) { hp=gethostbyname(servername); } else { addr=inet_addr(servername); hp=gethostbyaddr((char*)&addr,sizeof(addr),AF_INET); } if(hp==NULL) { closesocket(conn); return; }
The connect() function is used to establish a connection to the destination
server. We pass it the socket we created earlier as well as a sockaddr
structure. We populate the sockaddr with the host address returned by gethostbyname()/gethostbyaddr(), as well as enter a valid port to connect to.
server.sin_addr.s_addr=*((unsigned long*)hp->h_addr); server.sin_family=AF_INET; server.sin_port=htons(80); if(connect(conn,(struct sockaddr*)&server,sizeof(server))) { closesocket(conn); return; }
Once the socket connection is established the client and the server can
send() and recv() data between themselves. This is popularly referred to as TCP
chatting. In our particular case we need to HTTP chat, which is comparatively
simple when you consider other slightly more complicated protocols like SMTP or
POP3. The HTTP GET command is used to retrieve a file from the HTTP server. This
might be an HTML file or an image file or a zip or an MP3 or whatever. It is
send thus [in it's simplest form]. There are other slightly more complex ways of
using this command.
GET http-path-to-file\r\n\r\n
And in our program we do something like this to send the GET command :-
sprintf(buff,"GET %s\r\n\r\n",filepath); send(conn,buff,strlen(buff),0);
Once we have send the command we know that the server is going to start
sending us the file we just requested. Just as we used send() to send our
command we can use recv() to receive the data that the server is going to send
us. We loop on recv() till it returns zero when we understand that the server
has finished sending us the data. And in our particular case we write all this
data to a file as our intention is to download and save a file.
while(y=recv(conn,buff,512,0)) { f.Write(buff,y); }
Now that our chat is over, we must close the connection. In our case the HTTP
connection is closed by the server the moment it finishes sending the file, but
that doesn't matter. We need to close our socket and release the resource. In
more complex chats we usually call shutdown() before we call closesocket() to
ensure that the buffers are flushed. Otherwise we might encounter some data
loss.
closesocket(conn);
We call WSACleanup() to conclude our usage of WinSock.
WSACleanup();
Thank you.
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 28 Feb 2002 Editor: Chris Maunder |
Copyright 2002 by Nishant Sivakumar Everything else Copyright © CodeProject, 1999-2009 Web18 | Advertise on the Code Project |