Results 1 to 7 of 7
Hi again,
I have been developing some code which I have been testing an another i386 system. However I have been getting some weird data received on a socket.
I ...
- 09-20-2010 #1Just Joined!
- Join Date
- Jul 2010
- Posts
- 25
Weird recv() problem, buffer back to front?
Hi again,
I have been developing some code which I have been testing an another i386 system. However I have been getting some weird data received on a socket.
I am communicating with some 3rd party hardware, I have opened a socket to read data on the hardware's telnet port. The data being read is as expected and my code appears to function correctly.
However I have now began testing the code on a target platform, this platform is of a better spec than my development system. When I read data from the socket using recv(), all the expected data has not been read. A chunk of data from the beginning is missing and a portion of data that would be at the end is now at the beginning of the buffer. I'll try and illustrate this below.
Code://Expected data in buffer when printed to screen 1 2 3 4 5 6
Though the target platform is of a better spec, the biggest difference is that the target platform has DDR3 memory in it. A shot in the dark but could this be an issue?Code://What is actually being printed to screen from buffer 5 6 3 4
Due the buffer being messed up I get random seg faults from strstr calls that perform on the buffer.
An odd one? Any ideas would be appreciated as I am struggling to debug this.
Cheers
- 09-20-2010 #2Linux Newbie
- Join Date
- Mar 2010
- Posts
- 121
Are you making sure that (i) everything is getting transferred in network byte order and (ii) everything is getting converted to local byte order on the local machine? If these are ASCII characters and you weren't doing this (and the two machines have a different endianness), then the (presumably) expected "0x31323334 0x35360000" (ASCII "123456" with two trailing 0's) might be turned into "0x34333231 0x00003635".
Check out `man ntohs' for how you can convert between host and network byte order.
- 09-20-2010 #3Just Joined!
- Join Date
- Jul 2010
- Posts
- 25
- 09-20-2010 #4Linux Newbie
- Join Date
- Mar 2010
- Posts
- 121
It would only occur if the data received through recv() is 8 bit character data being treated as 32 bit integers at some stage (possibly even before it's sent?). If other places treat is as 8 bit character data they won't see this problem.
It may not be that, just a thought on something to double-check. Possibly the best thing to do is get a Wireshark trace of the data and see what's actually on the wire.
- 09-23-2010 #5Linux Guru
- Join Date
- Apr 2009
- Location
- I can be found either 40 miles west of Chicago, or in a galaxy far, far away.
- Posts
- 8,974
You don't say if you are using the same OS and kernel on both systems. Also, you don't provide any code to see how you are setting up the connection and then using it. Please do so.
Sometimes, real fast is almost as good as real time.
Just remember, Semper Gumbi - always be flexible!
- 09-24-2010 #6Just Joined!
- Join Date
- Jul 2010
- Posts
- 25
Both systems are using 2.6.34.6-54.fc13.i686.
As for some code here we go, just to reiterate in the function InetTelnetReadUntil when I printf the buffer contents the reordering of the contents can happen randomly.
Cheers
Code:int InetTelnetOpen(const char *telnetServer, unsigned short remotePort) { int sd; struct sockaddr_in sin; int on; //Create TCP Socket sd = socket(AF_INET, SOCK_STREAM, 0); if(sd < 0){ Die("Failed to create socket"); return -1; } on = 1; setsockopt( sd, SOL_SOCKET, MSG_NOSIGNAL, &on, sizeof(on) ); //Consrcut the server sockaddr_in structure memset(&sin, 0, sizeof(sin)); //clear structure sin.sin_family = AF_INET; //Internet/IP sin.sin_addr.s_addr = inet_addr(telnetServer); //IP address sin.sin_port = htons(remotePort); //Establish the connection if(connect(sd, (struct sockaddr*)&sin,sizeof(sin))<0){ Die("Failed to connect to server"); return -1; } return (sd); } int InetTelnetReadUntil(int hSocket, char *readBuffer, size_t readLength, const char *stringToMatch, unsigned int timeout) { int j; char *pMatchedString = NULL; memset(readBuffer, 0, readLength); while(!pMatchedString) { j = 0; int bytes = 0; bytes = recvtimeout(hSocket, readBuffer, readLength, timeout); if(bytes==-2){ Die("Timeout"); return -2; } if(!bytes){ Die("No Bytes Read"); return -3; } pMatchedString = strstr(readBuffer, stringToMatch); if(pMatchedString) { system("clear"); printf("%s\n", readBuffer); //debug: print buffer to visually verify for(j=0; j<strlen(stringToMatch); j++) pMatchedString++; pMatchedString[0] = '\0'; } } return 0; } int recvtimeout(int s, char *buf, size_t len, int timeout) { fd_set fds; int n = 0; struct timeval tv; //set up the file descriptor set FD_ZERO(&fds); FD_SET(s,&fds); //set up the struct timeval for the timeout tv.tv_sec = timeout; tv.tv_usec = 0; //wait until the timeout or data received n = select(s+1, &fds, NULL, NULL, &tv); if(!n) return -2; //timeout if(n==-1) return -1; //error //data must be here, so do a normal receive return recv(s, buf, len, 0); }
- 09-24-2010 #7Linux Guru
- Join Date
- Apr 2009
- Location
- I can be found either 40 miles west of Chicago, or in a galaxy far, far away.
- Posts
- 8,974
Ok. The code seems, at first glance, to be reasonable. I take it that the 3rd party hardware is a separate piece of equipment on the network? As you are connecting with a TCP, not a UDP socket, then the data should appear to your application in the order sent. It is possible that the ethernet hardware on the newer/faster system is not working correctly. However, if other network connections are working correctly then I would tend to doubt that. Sorry, but at this point I can't think of anything further to consider other than trying on another computer or with another ethernet board to see if that has the same problem.
Sometimes, real fast is almost as good as real time.
Just remember, Semper Gumbi - always be flexible!


Reply With Quote
