ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I'm trying to debug a small C++ routine that connects to a listening socket (on another machine) and sends/receives messages.
This should be a simple task but I've come across incredible problems which I can't sort out.
The routine is like this:
a) I connect to the listening socket using connec()
b) Send message on that socket
c) Use select() to wait for response from the peer
d) Send message again on the same socket (ignoring the select() return)
e) loop like this until I say stop!!!!
The problem lies in part d). It never sends the data for the second time and onwards eventhough the send() function doesn't return any error. It seems so that I can only send data once on a connecting socket.
Is that correct or am I not doing this right??
Here is the while loop doing the send(),select() and recv()
Code:
while (1)
{
//sleep(2);
cout << "Sending data to peer - data: " << sSendBuffer << endl;
cout << "bytes sent: " << send(iSocket, sSendBuffer, sizeof(cBuffer), 0) << endl;
cout << "Waiting for response!!" << endl;
FD_ZERO(&sSockets);
FD_SET(iSocket, &sSockets);
sTimeout.tv_sec = 5;
sTimeout.tv_usec = 0;
// Select()
iNumSocket = select(iSocket + 1, &sSockets, NULL, NULL, &sTimeout);
if (iNumSocket < 0)
{
cout << "Select failed!" << endl;
}
else if (iNumSocket == 0)
{
cout << "Timed out " << endl;
}
else if (FD_ISSET(iSocket, &sSockets))
{
// Read from the socket
memset (cBuffer, 0, sizeof(cBuffer));
int iNumRead = recv(iSocket, cBuffer, 48, 0);
// If recv() returned 0 bytes it means that the remote host
// has closed the socket!
if (iNumRead <= 0)
{
cout << "Read failed" << endl;
}
cout << "Server responded: " << cBuffer << endl;
}
++iCount;
sprintf(sSendBuffer,"GETMSG:%d", iCount);
}
This may not be causing any problems but I noticed that you are using sizeof(cBuffer) as the third argument to send. It looks to me that it should be sizeof(sSendBuffer).
One other thing, Could it be that the recv() call, made by the server, is closing the socket after receiving ????
Is that standard configuration and if so, how can it be changed.
The following program is your code combined into a single function: test() . I ran it on my local machine and ran "netcat -l -p 20000" to act as a server. This seemed to work fine.
You might want to try this as well on your machine. If it works, then the problem probably is that your remote server is not behaving as you expect.
To answer your question, resetting the socket after a recv is not default behavior but the server could do it anyway for some reason. Tcpdump ad/or ethereal might give you some useful diagnostics.
- Dave
Code:
#include <stdio.h>
#include <memory.h>
#include <iostream>
#include <resolv.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
using namespace std;
char cBuffer[512];
char* sSendBuffer = cBuffer;
bool test()
{
char *cAddress = "localhost";
struct hostent *pHost;
struct sockaddr_in sAddr;
int iOpt = 1;
fd_set sSocket, sError;
struct timeval sTimeout;
int iReadSocket;
if ((pHost = gethostbyname(cAddress)) == NULL)
{
return false;
}
int iSocket;
if ((iSocket = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
return false;
}
setsockopt(iSocket, SOL_SOCKET, SO_REUSEADDR, &iOpt, sizeof(iOpt));
memset((char *) &sAddr, 0, sizeof(sAddr));
sAddr.sin_family = AF_INET;
uint16_t iPort = 20000;
sAddr.sin_port = htons(iPort);
sAddr.sin_addr = *((struct in_addr *) pHost->h_addr);
if (connect(iSocket, (struct sockaddr *) &sAddr, sizeof(struct sockaddr)) == -1)
{
return false;
}
unsigned int iCount = 0;
while (1)
{
//sleep(2);
cout << "Sending data to peer - data: " << sSendBuffer << endl;
cout << "bytes sent: " << send(iSocket, sSendBuffer, sizeof(cBuffer), 0) << endl;
fd_set sSockets;
struct timeval sTimeout;
int iNumSocket;
cout << "Waiting for response!!" << endl;
FD_ZERO(&sSockets);
FD_SET(iSocket, &sSockets);
sTimeout.tv_sec = 5;
sTimeout.tv_usec = 0;
// Select()
iNumSocket = select(iSocket + 1, &sSockets, NULL, NULL, &sTimeout);
if (iNumSocket < 0)
{
cout << "Select failed!" << endl;
}
else if (iNumSocket == 0)
{
cout << "Timed out " << endl;
}
else if (FD_ISSET(iSocket, &sSockets))
{
// Read from the socket
memset (cBuffer, 0, sizeof(cBuffer));
int iNumRead = recv(iSocket, cBuffer, 48, 0);
// If recv() returned 0 bytes it means that the remote host
// has closed the socket!
if (iNumRead <= 0)
{
cout << "Read failed" << endl;
}
cout << "Server responded: " << cBuffer << endl;
}
++iCount;
sprintf(sSendBuffer,"GETMSG:%d", iCount);
}
}
main()
{
test();
}
Last edited by YetAnotherDave; 10-04-2005 at 05:39 PM.
hi
this is a tcp buffer problem and I have tried pretty much everything to work around it so I wan to ask how is it best to ensure instant delivery using tcp sockets. I know that many people have had this problem and I've followed those instructions I have read but without any result.
I check the result from recv() and send() to insure that everything has been received and sent. But the send() function always halts after the second time,,,,,
Hope somebody has had similar problems and SOLVED it.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.