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 07-30-2011, 09:48 PM   #1
rajeshwar27singh
LQ Newbie
 
Registered: Oct 2007
Posts: 11

Rep: Reputation: 0
Unpredictable behaviour with send/recv system call


Hi,

I am making a library, but I am facing a strange problem while sending data over network using ethernet.

I am sending 39 bytes of the data from one server to slave application but some time slave receives 39 bytes and some time it receives 29 bytes. And when ever slave receives 29 bytes all the memories to which my pointers are pointing get changed.

This problem is only when I am sending data from the server to slave, while sending data from slave to server I am facing no such issue.

Have anybody faced such issue before.

Regards,
Rajeshwar Singh Bisht
 
Click here to see the post LQ members have rated as the most helpful post in this thread.
Old 07-30-2011, 10:15 PM   #2
paulsm4
Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
Quote:
I am sending 39 bytes of the data from one server to slave application but some time slave receives 39 bytes and some time it receives 29 bytes
You are NOT guaranteed to get all the data that was written all at once. You should read in a loop, until all expected data is received, or until an error occurs.

Quote:
And when ever slave receives 29 bytes all the memories to which my pointers are pointing get changed.
Sounds like buffer overrun.
Q: Are you sure you're allocating enough space for the data buffer?
Q: Are you interpreting the data read correctly? For example, perhaps you're expecting "0x0a" (10), but you're receiving "0x0a00" (2560)?
Q: Have you stepped through under the debugger, and looked at the actual bytes being received (which you receive 29 bytes, instead of the expected 39)?
 
3 members found this post helpful.
Old 07-30-2011, 10:16 PM   #3
Web31337
Member
 
Registered: Sep 2009
Location: Russia
Distribution: Gentoo, LFS
Posts: 399
Blog Entries: 71

Rep: Reputation: 65
Well, what's the actual problem here? Test your networking hardware first.
And you have to ensure received data is correct and full in your application, it's a logical programming question. Your application MUST be ready for such unpredicatble behaviour.
Take good care of memory, please.

Last edited by Web31337; 07-30-2011 at 10:18 PM.
 
Old 07-31-2011, 01:34 AM   #4
jschiwal
Guru
 
Registered: Aug 2001
Location: Fargo, ND
Distribution: SuSE AMD64
Posts: 15,733

Rep: Reputation: 654Reputation: 654Reputation: 654Reputation: 654Reputation: 654Reputation: 654
Moved: This thread is more suitable in the Programming Forum and has been moved accordingly to help your question get the exposure it deserves.
 
Old 07-31-2011, 04:27 AM   #5
rajeshwar27singh
LQ Newbie
 
Registered: Oct 2007
Posts: 11

Original Poster
Rep: Reputation: 0
@paulsm4: Thanks for the reply. I have allocated enough memory for the data to be received. If we think logically, if memory is big enough for 39 bytes it should also work with 29 bytes but that is whats not happening.

I also tried looping around the send and recv call and tried sending data 1 byte at a time. There is still data loss and interestingly its always first 10 bytes which go missing. Although after looping even though I am still getting 29 bytes instead of 39 bytes but my pointers are not changing their address which works with me.

The string which I am supposed to receive is in following format:
"<two string with no spaces in them and separated by _>:<pid of the application>:<hostname>"
eg "slave_master:2134:mylaptop"
where : are my delimiters.

When I change the following string "<two string with no spaces in them and separated by _>" I found that slave only receive last 4 characters of this string, if this string is of 10 bytes then first 6 bytes go missing and if it is of 14 bytes then first 10 bytes go missing.

As per the application requirement I do need require the first part before the first delimiter but I would be thankful to you if you could help me with it.

Regards,
 
Old 07-31-2011, 05:21 AM   #6
JohnGraham
Member
 
Registered: Oct 2009
Posts: 467

Rep: Reputation: 138Reputation: 138
I'd use Wireshark to see what's happening on the network, and that'll show you if your server is sending all the data correctly - then use a debugger to step through the code around the server's send()/the client's recv(), as appropriate. Although I suspect your problem is with the client's recv() - and since you also see pointers getting changed, this definitely sounds like some sort of memory corruption. When using the debugger, trace all calls around the recv() and try and find out when things get changed.
 
1 members found this post helpful.
Old 07-31-2011, 06:14 AM   #7
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,522

Rep: Reputation: 332Reputation: 332Reputation: 332Reputation: 332
Quote:
Originally Posted by rajeshwar27singh View Post
When I change the following string "<two string with no spaces in them and separated by _>" I found that slave only receive last 4 characters of this string, if this string is of 10 bytes then first 6 bytes go missing and if it is of 14 bytes then first 10 bytes go missing.
Can you please show how you are declaring the buffer for the string, how you are putting it together to form "master_slaveort:host", and then lastly, how you are sending it?
 
Old 08-01-2011, 05:23 AM   #8
rajeshwar27singh
LQ Newbie
 
Registered: Oct 2007
Posts: 11

Original Poster
Rep: Reputation: 0
I am using sprintf to join 4 different kind of data into a string. Size of
void identitydata[1024 * 4];
sprintf (identitydata, "%s:%d:%s:%s:%s", indentifier, MasterPid, hostname, ip, port);

This string is then stored into a file. All the data is getting stored into the file properly and when read back it is retrieved back properly.

fscanf(inputfile, "%s", data)

for sending data I have used the following loop.

for (counter = 0; counter < size; counter++){
if ((error = send (recvfd, &regdata[counter], sizeof(char), 0)) == -1){
perror ("Error in Sending data");
exit(1);
}
}
 
Old 08-01-2011, 05:44 AM   #9
JohnGraham
Member
 
Registered: Oct 2009
Posts: 467

Rep: Reputation: 138Reputation: 138
Quote:
Originally Posted by rajeshwar27singh View Post
sprintf (identitydata, "%s:%d:%s:%s:%s", indentifier, MasterPid, hostname, ip, port);
I would urge you to use snprintf(), just in case you unexpectedly end up with a huge string somewhere.

Have a look at what's going on over the network with Wireshark - there really is no substitute for this. Then debug the function going wrong (like I said, it sounds like the recv() part of your client).
 
Old 08-01-2011, 06:39 AM   #10
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,522

Rep: Reputation: 332Reputation: 332Reputation: 332Reputation: 332
Quote:
Originally Posted by rajeshwar27singh View Post
I am using sprintf to join 4 different kind of data into a string. Size of
void identitydata[1024 * 4];
sprintf (identitydata, "%s:%d:%s:%s:%s", indentifier, MasterPid, hostname, ip, port);

This string is then stored into a file. All the data is getting stored into the file properly and when read back it is retrieved back properly.

fscanf(inputfile, "%s", data)

for sending data I have used the following loop.

for (counter = 0; counter < size; counter++){
if ((error = send (recvfd, &regdata[counter], sizeof(char), 0)) == -1){
perror ("Error in Sending data");
exit(1);
}
}
Here's some more questions...

1. How is 'data' declared?
2. How does the string within 'data' end up in 'regdata'?
3. Why are you sending one character at a time via the socket, instead of sending the entire string?
4. I'm not sure how 'regdata' is declared, but it would seem that you are sending the address of the value (character) within 'regdata'. Perhaps the & is not required?

A suggestion:
Code:
char data[1024];

/* read data from file... */

/* send data */
size_t bytes_sent = 0;

while (bytes_sent < strlen(data))
{
   ssize_t ret = send(sock, data + bytes_sent, strlen(data) - bytes_sent, 0);

   if (ret > 0)
   {
      bytes_sent += ret;
   }
   else if (ret < 0)
   {
      if (errno == EINTR || errno == EAGAIN)
        continue;

      perror("Failure to send.");
      break;
   }
}

Last edited by dwhitney67; 08-01-2011 at 06:53 AM.
 
Old 08-01-2011, 11:23 AM   #11
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,395
Blog Entries: 2

Rep: Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903
Quote:
Originally Posted by paulsm4 View Post
You are NOT guaranteed to get all the data that was written all at once. You should read in a loop, until all expected data is received, or until an error occurs.
This seems like the most obvious cause, and I wonder why the rest of the thread seems to have deviated from it. If the data needs to be sent as a complete datagram, perhaps the application requires the protocol UDP, rather than TCP. Especially for such small packet sizes, this seems like the most obvious solution. There is no way to force TCP to packetize data in any particular way. It is a stream oriented protocol, and only guarantees that the data will be received in the same order that it was sent. It does not guarantee anything about the size of the chunks that will be used along the way.

--- rod.
 
1 members found this post helpful.
  


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
unpredictable fencing behaviour (cman & fenced) boeboe2005 Linux - Server 0 03-14-2011 08:18 AM
log send, sendrec, recv and notify system calls xeon123 Other *NIX 1 02-04-2008 05:26 PM
unpredictable wireless behaviour Suse 10.9 ndiswrapper 1.2 davidhilbert Linux - Wireless Networking 1 10-17-2005 03:22 PM
is there a system call to send process to run in the background? feetyouwell Programming 4 10-01-2004 04:58 AM
NULL buffer in read sys call unpredictable jwstric2 Programming 3 09-02-2004 07:13 PM


All times are GMT -5. The time now is 09:04 PM.

Main Menu
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
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration