|

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
- Initialize WinSock library using
WSAStartup()
- Create a IPPROTO_TCP SOCKET using
socket()
- Retrieve host information using
gethostbyname()/gethostbyaddr()
- Connect to the server using the socket we created, using
connect()
- Send and Receive data using
send()/recv() till our tcp chat is over
- Close the socket connection using
closesocket()
- 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.
| You must Sign In to use this message board. |
|
| | Msgs 1 to 25 of 67 (Total in Forum: 67) (Refresh) | FirstPrevNext |
|
|
 |
|
|
I am using Windows Sockets 2 (winsock2.h) for a program that will connect to a host computer named MyHost that runs a HTTP server, listening on Port 80.
MyHost has DHCP enabled & the IP assigned to it automatically is, say 157.184.205.117.
My program connects to the host computer using its Hostname & not its IP address. (this is a requirement)
On running my program on my local computer:
1. I can successfully connect to MyHost using HTTP over TCP/IP on Port 80. 2. I can successfully send [send()] data to MyHost. 3. I can successfully receive [recv()] the response from MyHost.
All communication is absolutely fine & works well.
Now here's problem:
If now - I turn off DHCP on MyHost & provide it a static IP address, say 157.184.205.111 - my program cannot connect to MyHost anymore.
I have also observed the following:
1. If, from within my program, I try to resolve the IP address of MyHost using the gethostbyname() function & other calculations, I receive the same old IP address of MyHost (157.184.205.117) instead of the newly assigned static IP address (157.184.205.111).
2. If I PING to MyHost from the Windows XP Command Prompt, it tries to connect to the old IP address of MyHost (157.184.205.117) instead of the newly assigned static IP address (157.184.205.111). So pinging also fails.
3. If I try to open in Internet Explorer, the url "http://MyHost" it fails to open the address.
Before assigning the host the static IP address, everything worked fine: 1. My Socket program connected. 2. Ping worked. 3. Internet Explorer worked.
Does anyone know a way to work around this problem?
That the hostname "MyHost" will be used to connect to the host, is a requirement.
The whole thing is getting me confused. Someone please help. 
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
Hi, thanks for good code. In my local network works proxy server. So if i want to access some outside node (for example some kind of site) I must go through that proxy. How I can do that in your program ?
Harviz
|
| Sign In·View Thread·PermaLink | 1.00/5 (1 vote) |
|
|
|
 |
|
|
hi, I took the image from the web camera as frame and convert the raw image to the jpeg file by using OpenCV program which is the C library.Later I read the image and send it from client to server with stream sockets.But I want to send the image synchronizingly as soon as takng from web camera.I think I don't need to save the frame as a file.How can I achieve this.I wil be so happy if you help me. I can also send the code as well. //client.cpp version = MAKEWORD(1,1);
WSAStartup(version,(LPWSADATA)&wsaData);
LPHOSTENT hostEntry;
//store information about the server hostEntry = gethostbyname("192.168.1.3");
if(!hostEntry) { cout<<"Failed gethostbyname()"; //WSACleanup(); return(0); }
//create the socket SOCKET theSocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if(theSocket ==-1) { cout<<"Failed socket()"; return (0); }
//Fill in the sockaddr_in struct SOCKADDR_IN serverInfo;
serverInfo.sin_family = PF_INET; serverInfo.sin_addr = *((LPIN_ADDR)*hostEntry->h_addr_list);
serverInfo.sin_port = htons(8888);
rVal=connect(theSocket,(LPSOCKADDR)&serverInfo, sizeof(serverInfo)); if(rVal==-1) { cout<<"Failed connect()"; return(0); } ifstream in; in.open("myimage.bmp",ios::binary); in.seekg(0,ios::end); int size=in.tellg(); in.seekg(0,ios::beg); char *buf=new char[size]; in.read(buf,size); in.close(); //char *buf = "simpleservermessage\n"; char sizeBuf[6]; itoa(size,sizeBuf,10); rVal = send(theSocket, sizeBuf, 6, 0); rVal = send(theSocket, buf, size, 0);
if(rVal ==-1) { cout<<"Failed send()"; return(0); }
closesocket(theSocket); cout << "closing client"<< endl; WSACleanup(); delete[] buf; return CS_OK; }
void sError(char *str) { MessageBox(NULL, str, "SOCKET ERROR", MB_OK); WSACleanup(); }
//server.cpp WORD sockVersion; WSADATA wsaData; int rVal;
sockVersion = MAKEWORD(1,1); //start dll WSAStartup(sockVersion, &wsaData);
//create socket SOCKET s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if(s == INVALID_SOCKET) { socketError("Failed socket()"); WSACleanup(); return SERVER_SOCKET_ERROR; }
//fill in sockaddr_in struct
SOCKADDR_IN sin; sin.sin_family = PF_INET; sin.sin_port = htons(8888); sin.sin_addr.s_addr = INADDR_ANY;
//bind the socket rVal = bind(s, (LPSOCKADDR)&sin, sizeof(sin)); if(rVal == SOCKET_ERROR) { socketError("Failed bind()"); WSACleanup(); return SERVER_SOCKET_ERROR; }
//get socket to listen rVal = listen(s, 2); if(rVal == SOCKET_ERROR) { socketError("Failed listen()"); WSACleanup(); return SERVER_SOCKET_ERROR; }
//wait for a client SOCKET client; cout << "waiting for newclient" << endl;
client = accept(s, NULL, NULL);
cout << "newclient found" << endl;
if(client == INVALID_SOCKET) { socketError("Failed accept()"); WSACleanup(); return SERVER_SOCKET_ERROR; } readline(&client); //close process closesocket(client); closesocket(s);
WSACleanup(); cout << "closing down"<< endl; ; return SOCKET_OK; };
char * readline(SOCKET *client) { char sizeBuf[6]; char *buffer; recv(*(client), sizeBuf, 6, 0); int size=atoi(sizeBuf); cout<<"Comming file size:"<<size<<endl; buffer=new char[size]; recv(*(client), buffer, size, 0); ofstream out; out.open("myimage_sended.jpg",ios::binary); out.write(buffer,size); out.close(); delete[] buffer; return buffer; }
void socketError(char* str) { MessageBox(NULL, str, "SERVER SOCKET ERROR", MB_OK); };
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
i have this problem. i am doing webserver optimization project.i have some error and how to connect client and server.please give the codings and explain.please give anyone immediately..please.....
Thanks & Recards Ilaya Raja
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hii... I hav used afxsock.h and winsock2.h.....compiler tells 69 redefinition error...plz help me how to fix this prob... I have to use WSAIoctl ..
|
| Sign In·View Thread·PermaLink | 1.00/5 (1 vote) |
|
|
|
 |
|
|
i think a good way to learn programming is to write programs, i m a newbie into network programming and would like to do some useful application, if u can sujjest me some good application that i can do within 10 to 15 days, it would be very helpful. i m aleady through with the basics but want to do some intelligent application.
Regards,
Dhaval
|
| Sign In·View Thread·PermaLink | 1.25/5 (5 votes) |
|
|
|
 |
|
|
Hi, i need help,i developing one application in vc++. which is used socket and user interface thread.pl help me simple ways to handle in applcation.I likes option to start server and stop server of server socket with handle client recv()/ send() funtion continuous till server runing.i am new to socket and thread. thanks
Thanks, Anji.Manchikanti
|
| Sign In·View Thread·PermaLink | 4.00/5 (2 votes) |
|
|
|
 |
|
|
I had some problems retrieving information from servers using this code. I modified the request header from:
sprintf(buff,"GET %s\r\n\r\n",filepath);
To:
sprintf( buff, "GET %s HTTP/1.1\r\nHost: %s\r\n\r\n", filepath, servername );
This allowed me to grab index.html from a website. Note that the response will return header information that needs to be stripped out before you use the file. Here's two different header two sections (the first was the header to an index.html file and the second is the header to a php file request). An easy way to strip off this header information might be to look for the first completely empty line - in other words, search for the first "\r\n\r\n". It will appear after the header information. (Of course, if you're just looking to download a file off of a server, you can probably use CHttpFile. It's easier.)
HTTP/1.1 200 OK Date: Mon, 26 Jun 2006 02:13:21 GMT Server: Apache Last-Modified: Tue, 13 Jun 2006 07:24:51 GMT ETag: "bf80b8-57e5-448e6843" Accept-Ranges: bytes Content-Length: 22501 Content-Type: text/html
HTTP/1.1 200 OK Date: Mon, 26 Jun 2006 02:30:49 GMT Server: Apache X-Powered-By: PHP/4.3.11 Transfer-Encoding: chunked Content-Type: text/html
----------------------------------------------------- Empires Of Steel[^]
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
hi , i tried the project...it is nt connecting to server.it s got stuck with that message hostname/ipaddress resolved..is anyone have same experience?plz help me suggest a solution
Rakesh K R, Software Engineer, Flextronics Software Systems
|
| Sign In·View Thread·PermaLink | 3.50/5 (2 votes) |
|
|
|
 |
|
|
Hello all !!!
How to delegate notification functions from the dll application to client using it ? To be more precise I have made a class that derives from CAscynSocket that handles all the network protocol details. Now when messages are received I parse the type of message received and simply want notifications to be sent to the client application depending upon the type of messages received.
I think callback function is the solution but I am stuck how to implement it ? Can somebody help me.
Thanks, Amir Shrestha
|
| Sign In·View Thread·PermaLink | 1.00/5 (1 vote) |
|
|
|
 |
|
|
Hello Nishanth,
I saw your post and it is good. But i am having some problems.. Actually i want to do a program which can communicate between systems using their IP addresses. I downloaded you client program and i have also went through your server program..I am using SMTP so it is giving Connection refuse error when i try to connect to a system. I am using the Port address 25, but which address family should be used. Please help me..it's urgent.
Thanks in advance, Poornima.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
   Can you give convert this simple TCP client using .NET (window form Application)?
I really need in .NET syntax..
TQ
Salwa
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
i am trying to make client server application as given MDSN now i got one server app and one client app and i m able to connect client to the server my problem is i am not getting the data which server is sending to client on client app on server it is shown that byte sent but on client no data is coming how to solve it
subh
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hello all, I want to write a program in Visual C++ to transfer data between 2 computers via 10/100 Ethernet RJ-45. Where should I start? Are there any sample codes available on this topic? Thanks very much in advance for your help. Miekie
|
| Sign In·View Thread·PermaLink | 1.29/5 (4 votes) |
|
|
|
 |
|
|
How do i acheive the Winsock Programming under Oracle Developer 2000 Forms 6i.
I would appreciated if you could help me out in this.
Regards
Krishnan L R
|
| Sign In·View Thread·PermaLink | 1.00/5 (2 votes) |
|
|
|
 |
|
|
I recently started my own TCP client project and I used your code for reference and it helped me a lot! Wow what can't you do?
-Ryan M.
|
| Sign In·View Thread·PermaLink | 5.00/5 (1 vote) |
|
|
|
 |
|
|
There is something to say for "out of the box." And you have definitely got that down. Thanks.
|
| Sign In·View Thread·PermaLink | 5.00/5 (2 votes) |
|
|
|
 |
 | hallo |  | psyKadeliKa | 0:02 28 Nov '03 |
|
|
hi, oru mallu de koravu undayirunnu. nan bangaloreil ninnaanu. my interest vc/OpenGL (started looking into winsock recently). evideya work cheyyunne rgds mathai
"if it aint broke... dont fix it"
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hi, I encounted a "debug assertion failed" problem while running the code.
Debug assertion failed! Program:SimpleTCPClientSrc\Debug\SimpleTCPClient.exe File:filecore.cpp Line:244
Can someone give me some pointers with regard to the problem? Thank you!
|
| Sign In·View Thread·PermaLink | 1.00/5 (1 vote) |
|
|
|
 |
|
|
Looks like you trie downloading from a page without a file name
you should change CString fname="c:\\"; to CString fname="c:\\default"; in CSimpleTcpClientDlg::DownloadFile();
Between, what's wrong with that code - it really doesn't download from not dedicated servers... What are the params to http we need to add?
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
it is neccessary that there will one socket server and a socket client.I think when we are connecting to telnet then there will be one socket who will send the data to desired telnet address .
|
| Sign In·View Thread·PermaLink | 1.57/5 (4 votes) |
|
|
|
 |
|
|
tried it with http://www.google.com/index.html ? and with http://www.google.com/images/logo.gif ?
it seems only to write empty files unless I go with the example he gave (http://www.codeproject.com/info/stuff/codeproject_w2k_bg.gif) what is that I don't know ? if you can help a beginner, thx.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I got the same results.. I tried it with various downloads, some files would have zero length, others would only retrieve a few kilobytes.
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
Hello nishant/all I have some trouble with socket programming , as I came to know about your experience from ur postings I am confident that you will help me . I am listing out my problem below : I am trying to develope a proxy server for shoutcast server . Usually the DFP Plug In of winAmp enables connection to a shoutcast server and streams the voice data in mp3 format to it . The DSP Pulg In connects to a server bt inputting the server's IP + port number where its listening for requests for connection.So after the connection is established with the server at the IP+port specified the DSP Plug In streams voice data to the server .The shoutcast server in turn streams the incoming voice data to listeners.The listeners connect to the Shoutcast server at its port and ip and listen to the broadcast coming out of the shoutcast server . But as the shoutcast server is designed for radio broadcast there is an acute delay of about 20 seconds for the voice to be heard at the client end . So in order to reduce the latency I am trying to write a proxy server that will listen from the DSP plug In in the place of Shoutcast server and the proxy will in trun redirect the stream to shoutcast server so that now shoutcast server broadcasts it to the clients.I also found that the DSP pulgIn of winamp from the broadcaster side is of type TCP so i created a server socket as below if ((sSock= socket (AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { AfxMessageBox("server creation failed"); }
sockaddr.sin_family = AF_INET; sockaddr.sin_port= htons(m_Port); sockaddr.sin_addr.s_addr=inet_addr("192.168.0.101"); bind (sSock, (struct sockaddr*) &sockaddr, sizeof (sockaddr)); listen (sSock, 5); HWND hwnd= GetSafeHwnd(); WSAAsyncSelect(sSock,hwnd,CONNECT_MESSAGE,FD_ACCEPT); here the sSock is the server socket and its initialized to the port + ip and in the WSAAsyncSelect() i have used a CONNECT_MESSAGE to be fired in case of Connection attempts from clients .And In the handler function of the CONNECT_MESSAGE I am call accept() to accept this new client but the DSP is not connecting and if I debug the server appln it is not even receiving any connection attempts .I used ur simple TCP server (console ) also but its not receiving any attempted connections . So please advise me how i can solve this problem . Help me by ur ideas with regards Dharani babu dharanibabus@hotmail.com
dharani
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
General News Question Answer Joke Rant Admin
|