LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 10-04-2005, 06:38 AM   #1
marri
Member
 
Registered: May 2004
Posts: 38

Rep: Reputation: 15
Socket programming problems


hi

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);
}
here is the connect function

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

  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;
  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;
  }	
  return true;
Hope you can assist me.

regards
Marri

Last edited by marri; 10-04-2005 at 07:41 AM.
 
Old 10-04-2005, 05:05 PM   #2
YetAnotherDave
Member
 
Registered: Feb 2005
Posts: 95

Rep: Reputation: 17
Hi,

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


cout << "bytes sent: " << send(iSocket, sSendBuffer, sizeof(cBuffer), 0) << endl;
 
Old 10-04-2005, 05:13 PM   #3
marri
Member
 
Registered: May 2004
Posts: 38

Original Poster
Rep: Reputation: 15
thanks for the reply.

But the cBuffer is defined as follows:

char cBuffer[512];

and then the sSendBuffer is defined as follows:

char* sSendBuffer = cBuffer;

this definition does the same as malloc().

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.

regards
Einar
 
Old 10-04-2005, 05:30 PM   #4
YetAnotherDave
Member
 
Registered: Feb 2005
Posts: 95

Rep: Reputation: 17
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.
 
Old 10-06-2005, 03:59 AM   #5
marri
Member
 
Registered: May 2004
Posts: 38

Original Poster
Rep: Reputation: 15
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.

Marri
 
Old 10-06-2005, 04:11 PM   #6
paulsm4
LQ Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
setsockopt (TCP_NODELAY)?
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
problems receving data in socket programming stephenwalter Programming 5 09-29-2005 11:58 PM
socket programming iiit Programming 2 07-05-2005 04:02 PM
Socket Programming Chaitanyayardi Programming 6 10-22-2004 12:10 AM
want help in socket programming valib4u *BSD 2 09-11-2003 11:17 PM
socket programming herambshembekar Programming 3 04-13-2002 03:13 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 06:16 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration