Winsock recv is screwing with my variables!!

Started by
19 comments, last by csolar 21 years, 1 month ago
Can anyone tell me whats going on with my winsock program? Heres the code: for( int i = 1; i <= num_players; ++i ) { char rcvBuffer[10]; recv(s,rcvBuffer,10,0); if( rcvBuffer == "Moving" ) { recv(s,rcvBuffer,10,0); player.pos = rcvBuffer; cout << player.strUsername << " moved to " << rcvBuffer << endl; } } Heres exactly whats happening: I run the program, it gets to the first recv function. i = 1, it gets the message from s[1] (s is a socket, with a user at &#111;ne end), then, it resets i to 0! I have no idea why, or how, it just turns my variable into nothing! The &#111;nly way I can make it not change my i variable is if I put i as the last parameter. So the function looks like this: recv(s,rcvBuffer,200,i); It doesn't change i, but it doesn't recieve anything! I have other recv functions above this &#111;ne that don't do this. So I am very confused and frustrated. If anyone knows what I am doing wrong, then please tell me. </i> Programming is like sex; make &#111;ne mistake and you have to support it the rest of your life. <SPAN CLASS=editedby>[edited by - csolar &#111;n March 3, 2003 11:30:05 PM]</SPAN> <SPAN CLASS=editedby>[edited by - csolar &#111;n March 3, 2003 11:31:14 PM]</SPAN>
They can write what they like, so long as I get the royalties.
Advertisement
first, that''s not how you compare c-style strings.

second, problem is most likely elsewhere in your code.

third, without any error checking, you won''t get far.

fourth, recv doesn''t have to receive more than one byte per call, and you don''t account for this.
Not knowing what the rest of your code looks like (and the problem could lie therein) I don''t see anything noticably wrong, except that the only things you would (rarely) pass to the last parameter are MSG_PEEK and MSG_OOB (which might equate to the literals 1 and 2). You have an array of sockets I take it? Are your sending/receiving on all of these in the same thread? Have you considered spawning a new thread for each new client, because each call to recv blocks until it gets data or times out according to what options you have set on the socket. Each server and/or client should really run in a separate thread, the design of which gets a little tricky sometimes. ALSO, you should check the return value of recv and check for extened error information also in the event of a return value of SOCKET_ERROR.

ie,

int nReturn = recv(s,buffer, bufsize, 0);
if (nReturn == 0)
{
//socket disconnected
}
else if (nReturn == SOCKET_ERROR)
{
//check error condition
}
else
{
whatever
}

As gratifying as successfully hacking WinSock might be (I know, I''ve been there once upon a time), have you considered DirectPlay?
yes, I know that this isn''t very good code. But, I have been mostly concerned about that recv function. I havn''t changed anything else in my program because I have been tring to get this to work. I am positive that the problem is in that section of code, if not just the recv function. I ran the debugger, and when it got to this line:

recv(s,rcvBuffer,10,0);

i = 1, once it ran that line, i = 0. And yes, I do have a array of sockets. The array is 10 sockets big. It is declared like this: SOCKET s[10]; what I am trying to do with this code is to go through all of the sockets, and recieve any new info that the client on one end of the socket sent. Then I compare the string that I got with some predifened strings: Moving, Update, GetFile, etc. And if the recved string matches one of those, it does that code and sends the requested info back to the client. I guess that I am probably going about this all wrong. Maybe one of you could help out and post some code for me. I looked in the Networking and Multiplayer articles, and all I found was tutorials on how to set up winsock, not to send, receive, and compare msgs. Could someone point me to a good tutorial if I missed one?


Programming is like sex; make one mistake and you have to support it the rest of your life.
They can write what they like, so long as I get the royalties.
1. Since rcvBuffer will NEVER == "Moving" (you're comparing pointers), it is unlikely that your code ever even gets to the recv() call. (As niyaw noted, you can't compare character arrays with '=='. You use strcmp() to compare character arrays in C).

2. An array in C uses zero-based indexing. Your socket array goes from 0 to 9, NOT 1 to 10. If that's how you're doing array indexing throughout your code, it is very likely that you are hosing your stack and clobbering your local 'i' variable.

I would recommend that you go back through your code and make sure that you are using array indexes and string assignment/comparison properly.


[edited by - Dave Hunt on March 4, 2003 4:49:41 PM]
quote:Original post by csolar then, it resets i to 0!
Check your compiler setting. If you have turned on optimizations, your debugger may be confusing stack-based variables with registers.

-cb

I tried using strcmp before, and it was weird. It would return 1 at the beginning, and now its returning 0. With no change.

Also, the problem is with the first recv function. Not the secound. I included that extra code just to show what I am triing to do.

Finaly, the 0 index for s is the server''s own socket. Heres how its setup:

s[0] = Server socket
s[1] = Client
...
s[10] = Client

so I have to start the index at 1.

Programming is like sex; make one mistake and you have to support it the rest of your life.
They can write what they like, so long as I get the royalties.
Ok, I got it working. Heres what I did to fix it. First, I changed my socket array to two things. One, a server socket. Named ServerS. The other, an array of sockets for the clients. Called ClientS[MAX_PLAYERS]. And I changed my for loop to start at 0. I was still getting the same problem, so I studied the post that Dave Hunt made about hosing my stack. I assume that was the problem, because I made that i a static int and it solved the problem. Heres all the code.

for( static int i = 0; i < num_players; ++i ){	char rcvBuffer[10];				recv(ClientS,rcvBuffer,200,0);	int n = strcmp( rcvBuffer, "Moving" );	if( n == 0 )	{	        recv(ClientS,rcvBuffer,200,0);<br><br>		strcpy(player.pos, rcvBuffer);<br><br>		cout << player.strUsername << " moved to " << rcvBuffer << endl;<br>				<br>	}<br>}<br>		<br></pre><br><br>and that works.  So thanks to everyone who helped me figure out what was wrong.  If you still have any suggestions &#111;n how I can improve this, then I am still open.  My email is csolar1124@attbi.com if you want to contact me that way.<br><br>Thanks<br>-Charles  </i>   </pre> <br><br>Programming is like sex; make &#111;ne mistake and you have to support it the rest of your life.    
They can write what they like, so long as I get the royalties.
you didn''t fix the problem, you merely silenced its particular appearance.
Why, oh why, are you passing 200 as the buffer length when the array is only 10 bytes long?

This topic is closed to new replies.

Advertisement