5,446,542 members and growing! (18,484 online)
Email Password   helpLost your password?
General Programming » Internet / Network » Beginners     Beginner

Beginning Winsock Programming - Simple TCP client

By Nishant Sivakumar

A simple TCP client is explained.
VC6, C++Windows, Win2K, MFC, VS6, Visual Studio, Dev

Posted: 28 Feb 2002
Updated: 28 Feb 2002
Views: 304,834
Bookmarked: 116 times
Announcements
Want a new Job?



Search    
Advanced Search
Sitemap
84 votes for this Article.
Popularity: 8.55 Rating: 4.44 out of 5
1 vote, 1.9%
1
2 votes, 3.8%
2
0 votes, 0.0%
3
10 votes, 18.9%
4
40 votes, 75.5%
5

Introduction

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.

Program Flow of a simple TCP client

  1. Initialize WinSock library using WSAStartup()
  2. Create a IPPROTO_TCP SOCKET using socket()
  3. Retrieve host information using gethostbyname()/gethostbyaddr()
  4. Connect to the server using the socket we created, using connect()
  5. Send and Receive data using send()/recv() till our tcp chat is over
  6. Close the socket connection using closesocket()
  7. De-Initialize WinSock using WSACleanup()

Initialize WinSock

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;

Create the SOCKET

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;

Getting host information

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;
}

Connecting to the server

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;	
}

Chatting

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);
}

Close the connection

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);

De-Initialize WinSock

We call WSACleanup() to conclude our usage of WinSock.

WSACleanup();

Thank you.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Nishant Sivakumar


Sitebuilder, Mvp
Nish is a real nice guy living in Atlanta, who has been coding since 1990, when he was 13 years old. Originally from sunny Trivandrum in India, he recently moved to Atlanta from Toronto and is a little sad that he won't be able to play in snow anymore.

Nish has been a Microsoft Visual C++ MVP since October, 2002 - awfully nice of Microsoft, he thinks. He maintains an MVP tips and tricks web site - www.voidnish.com where you can find a consolidated list of his articles, writings and ideas on VC++, MFC, .NET and C++/CLI. Oh, and you might want to check out his blog on C++/CLI, MFC, .NET and a lot of other stuff - blog.voidnish.com

Nish loves reading Science Fiction, P G Wodehouse and Agatha Christie, and also fancies himself to be a decent writer of sorts. He has authored a romantic comedy Summer Love and Some more Cricket as well as a programming book – Extending MFC applications with the .NET Framework.

Nish's latest book C++/CLI in Action published by Manning Publications is now available for purchase. You can read more about the book on his blog.

Despite his wife's attempts to get him into cooking, his best effort so far has been a badly done omelette. Some day, he hopes to be a good cook, and to cook a tasty dinner for his wife.
Location: United States United States

Other popular Internet / Network articles:

Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Noise ToleranceSearch Search Messages 
 Layout  Per page   
 Msgs 1 to 25 of 67 (Total in Forum: 67) (Refresh)FirstPrevNext
Subject  Author Date 
QuestionConnecting with Hostname to host with Static IP Addressesmemberddas772:34 4 Sep '07  
GeneralGreat Examplememberisnainsd0:39 21 Aug '07  
Generalwhat if proxy server is used ?memberHarviz Harrison0:43 26 Apr '07  
Generalsynchronous windows socketmembermavsolos4:25 11 Apr '07  
Generalhow to implement webserver optimization project codingsmemberilaiah1:16 21 Mar '07  
GeneralRedefinition Errormemberdeepak.cse0720:45 10 Feb '07  
Generalnew to winsock programmingmemberdhavall22:03 8 Sep '06  
GeneralHow to do socket and user interface therad in vc++memberanjicafe4:25 30 Jun '06  
GeneralAdditional information for usersmemberBrit17:26 25 Jun '06  
Generalnot connecting to servermemberRakesh K R2:24 11 Feb '06  
Generalcallback function with winsocksmemberAmir Ram Shrestha20:19 24 Jul '05  
GeneralRegarding SMTPmemberPoornimaS21:43 7 Apr '05  
GeneralTQConvert in .NETmemberchal_adiera15:38 3 Mar '05  
Generalclient not receivingmembersubhashkjain2001@hotmail.com22:14 2 Feb '05  
GeneralEthernet ProgrammingmemberMiekie17:58 15 Sep '04  
GeneralWinsock ProgrammingmemberL.R. Krishnan22:59 23 May '04  
GeneralVery good code!memberRyan McDermott8:25 18 Mar '04  
GeneralExcellentmemberhesterloli19:47 8 Jan '04  
GeneralhallosusspsyKadeliKa0:02 28 Nov '03  
General"debug assertion failed" problemmemberdelphinidae16:33 4 Nov '03  
GeneralRe: "debug assertion failed" problemmemberfsdafsdfsad20:16 15 Dec '03  
Generaltelnet clientmembermohammad arif22:09 22 Oct '03  
Generaldoes it work???memberscovase5:24 18 Oct '03  
GeneralRe: does it work???sussAnonymous7:44 25 Jun '04  
Generalhelp! me for proxy servermemberdharani0:39 8 Aug '03  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 28 Feb 2002
Editor: Chris Maunder
Copyright 2002 by Nishant Sivakumar
Everything else Copyright © CodeProject, 1999-2008
Web18 | Advertise on the Code Project