sendin to specific client with udp

Started by
15 comments, last by etsuja 17 years, 11 months ago
ok, I tried sending to the client with the address and port I get from it but it still never receives anything.
Artist 1st - Programmer 2nd(I'll get some material linked here sometime to support these claims, haha)
Advertisement
To know the port assigned by the system, use ::getsockname().

If you use sendto() to reply back to the address you get from recvfrom(), you either have a bug in your code, or a bad firewall. You can use something like Ethereal on the client and server machines to sniff all UDP traffic, and see whether anything actually leaves the server machine when it attempts to reply.
enum Bool { True, False, FileNotFound };
I tried giving my server and client full access with my firewall and tried shutting it off but it still didn't work.... here's what I'm doing.

here's my servers send and receive function
void SendRcv(){		RcvTest = 0;	RcvTest = recvfrom(UDPSocket, RcvBuff, MAX_BUFFER, 0, (struct sockaddr *)&from, &len);	InBuffer = RcvBuff;	if(atoi(&InBuffer[0]) == PCKT_LOGIN)	{		AddString(TEXT("COOL"));				string ALoginName;		string APassword;		ACNTSTRUCT* ThisAccount = FirstAccount;		string ThisAccountName;		string ThisAccountPassword;		while(ThisAccount != NULL)		{			string::size_type Pos = InBuffer.find(ThisAccount->AcntLoginName,0);			if(Pos != string::npos)			{				string::size_type Pos = InBuffer.find(ThisAccount->AcntPassword,0);				if(Pos != string::npos)				{					service.sin_addr = from.sin_addr;					service.sin_port = from.sin_port;					if(ThisAccount->AcntLoggedIn == TRUE)					{						OutBuffer = "You already Logged in";						sendto(UDPSocket, OutBuffer.c_str(), sizeof(OutBuffer), 0, (SOCKADDR *)&service, sizeof(SOCKADDR));					}					else					{						OutBuffer = "You Logged in now";						sendto(UDPSocket, OutBuffer.c_str(), sizeof(OutBuffer), 0, (SOCKADDR *)&service, sizeof(SOCKADDR));						ThisAccount->AcntLoggedIn = TRUE;					}				}			}			ThisAccount = ThisAccount->Next;		}	}}


and here's my test clients. Does rcvfrom block the rest of the app from running? Its runningon a seperate thread on my server.
test = sendto(UDPSocket, buffer, sizeof(buffer), 0, (SOCKADDR *)&service, sizeof(SOCKADDR));	if(test == SOCKET_ERROR)	{		printf("no data sent");	}	if((test == SOCKET_ERROR) || (test < 0))	{		printf("FUCK!!");	}	else	{		printf("%s sent",buffer);	}	int testie = 0;		testie = recvfrom(UDPSocket, InBuffer, 256, 0, NULL, &len);	if(testie > 0)	{		printf("%s", InBuffer);		break;	}
Artist 1st - Programmer 2nd(I'll get some material linked here sometime to support these claims, haha)
I can't begin to describe how horrible that code is or for how many reasons. Do not, in the name of all that's holy, expect that stuff to work properly, especially when you need to send more complex messages.<br><br>Firstly, you're assuming you'll receive a string. Strings are zero terminated. Buffers are not. Assuming the data you've received is the data you want is wrong. And evil. And wrong.<br><br>When doing network coding you absolutely definitely MUST MUST MUST check the data you receive. Not doing so WILL end up with you having buffer overruns, heap violations and all sorts of hell as your app crashes in unrelated threads (a painful experience).<br><br>Why the atoi? I really don't follow what you're trying to do here. There's no packet format there - which is going to make debugging and packet-dumping (essential techniques) impossible. Here [<a href ="http://www.gamedev.net/community/forums/topic.asp?topic_id=387969">LINK</A>] is a thread going into UDP packet format - you need to look at this, and implement something similar so you know how much data you need to expect from a given buffer, and if the received buffer is complete, aggregated, or corrupt - UDP can and eventually is going to send you packets out of order, drop them, and generally be the unreliable beast it is. Also the help in debugging is invaluable - do it now, before it's too late. Edit: to those in the TCP camp, if nagling is active &#111;n the socket, it will aggregate small packets into a single transmission unit - each tick you might receive various chunks of packets (including a partial (truncated) packet). <br><br>You're using C++. Make use of it - wrapping sockets into classes is the &#111;nly way to go - encapsulation helps you keep bugs contained.<br><br>If you want to set your socket to non-blocking, this is done with ioctl, something like:<br><!–STARTSCRIPT–><!–source lang="cpp"–><div class="source"><pre>[source lang=cpp]<br><span class="cpp-keyword">bool</span> WSSocket::setBlocking(<span class="cpp-keyword">bool</span> bBlocking)<br>{<br> <span class="cpp-keyword">if</span> (!m_bReady) <br> {<br> m_pLog-&gt;log(<span class="cpp-literal">"WSSocket %x trying to set blocking mode before ready!\n"</span>,<span class="cpp-keyword">this</span>);<br> <span class="cpp-keyword">return</span> <span class="cpp-keyword">false</span>; <span class="cpp-comment">// Socket must be created to change mode</span><br> }<br><br> <span class="cpp-keyword">unsigned</span> <span class="cpp-keyword">long</span> val;<br><br><span class="cpp-directive">#ifdef</span> WSCORE_LINUX<br><br> <span class="cpp-keyword">if</span> (bBlocking)<br> {<br> <span class="cpp-comment">// We want to be blocking</span><br> val = <span class="cpp-number">0</span>;<br> <span class="cpp-keyword">if</span> (!m_bBlocking) <span class="cpp-comment">// We WANT to be blocking but we're NOT</span><br> {<br> <span class="cpp-keyword">if</span> (ioctl(m_sock, FIONBIO, &amp;val)&lt;<span class="cpp-number">0</span>)<br> <span class="cpp-keyword">return</span> <span class="cpp-keyword">false</span>;<br> m_bBlocking = <span class="cpp-keyword">true</span>;<br> <span class="cpp-keyword">return</span> <span class="cpp-keyword">true</span>;<br> }<br> <span class="cpp-keyword">return</span> <span class="cpp-keyword">true</span>; <span class="cpp-comment">// We blocking and we want to be</span><br> }<br> <span class="cpp-keyword">else</span><br> {<br> <span class="cpp-comment">// We don't want to be blocking</span><br> val = <span class="cpp-number">1</span>;<br> <span class="cpp-keyword">if</span> (m_bBlocking) <span class="cpp-comment">// We DON'T want to be blocking but we ARE</span><br> {<br> <span class="cpp-keyword">if</span> (ioctl(m_sock, FIONBIO, &amp;val)&lt;<span class="cpp-number">0</span>)<br> <span class="cpp-keyword">return</span> <span class="cpp-keyword">false</span>;<br> m_bBlocking = <span class="cpp-keyword">false</span>;<br> <span class="cpp-keyword">return</span> <span class="cpp-keyword">true</span>;<br> }<br> <span class="cpp-keyword">return</span> <span class="cpp-keyword">true</span>; <span class="cpp-comment">// We not blocking and we don't want to be</span><br> }<br><br><span class="cpp-directive">#endif</span><br><br><br><span class="cpp-directive">#ifdef</span> WSCORE_WIN32 <span class="cpp-comment">// ioctl only applies to sockets under linux - hence ioctlsocket.</span><br><br> <span class="cpp-keyword">if</span> (bBlocking)<br> {<br> <span class="cpp-comment">// We want to be blocking</span><br> val = <span class="cpp-number">0</span>;<br> <span class="cpp-keyword">if</span> (!m_bBlocking) <span class="cpp-comment">// We WANT to be blocking but we're NOT</span><br> {<br> <span class="cpp-keyword">if</span> (ioctlsocket(m_sock,FIONBIO,&amp;val)&lt;<span class="cpp-number">0</span>)<br> <span class="cpp-keyword">return</span> <span class="cpp-keyword">false</span>;<br> m_bBlocking = <span class="cpp-keyword">true</span>;<br> <span class="cpp-keyword">return</span> <span class="cpp-keyword">true</span>;<br> }<br> <span class="cpp-keyword">return</span> <span class="cpp-keyword">true</span>; <span class="cpp-comment">// We blocking and we want to be</span><br> }<br> <span class="cpp-keyword">else</span><br> {<br> <span class="cpp-comment">// We don't want to be blocking</span><br> val = <span class="cpp-number">1</span>;<br> <span class="cpp-keyword">if</span> (m_bBlocking) <span class="cpp-comment">// We DON'T want to be blocking but we ARE</span><br> {<br> <span class="cpp-keyword">if</span> (ioctlsocket(m_sock,FIONBIO,&amp;val)&lt;<span class="cpp-number">0</span>)<br> <span class="cpp-keyword">return</span> <span class="cpp-keyword">false</span>;<br> m_bBlocking = <span class="cpp-keyword">false</span>;<br> <span class="cpp-keyword">return</span> <span class="cpp-keyword">true</span>;<br> }<br> <span class="cpp-keyword">return</span> <span class="cpp-keyword">true</span>; <span class="cpp-comment">// We are not blocking and we don't want to be</span><br> }<br><br><span class="cpp-directive">#endif</span><br>};<br><br><br><br></pre></div><!–ENDSCRIPT–><br><br>Edit: Take note that the winsock equivalent of ioctl is ioctlsocket, since it &#111;nly applies to berkely sockets under windows.<br><br>I also just noticed you're apparently sending the login name with every packet? Don't do this - recvfrom can identify the client after the first receive from it (perhaps you may want an integer id (SERVER ASSIGNED) in messages, but not necessary). Until you can bounce simple messages back and forth between 2 machines don't worry about a login system. When you can bounce messages between 2 machines extend it to 3 then 4. THEN do a login system so you can identify each client. Then implement 'tell's and so &#111;n, and you're getting there.<br><br><!–EDIT–><span class=editedby><!–/EDIT–>[Edited by - _winterdyne_ on June 1, 2006 7:18:27 AM]<!–EDIT–></span><!–/EDIT–>
Winterdyne Solutions Ltd is recruiting - this thread for details!
ok, I'm just starting networking so excuse me if I don't know every little detail and the best coding for it. but this isn't the final code anyways I was just using this for testing. I'm also not sending the login name with every packet. the atoi was to check the first character in the packet to see what kind of packet it was and at the moment I was jest using my client to send strings. Anyways all I want to know is why my client isn't receiving anything or if the if statement just isn't running with the code provided.
Artist 1st - Programmer 2nd(I'll get some material linked here sometime to support these claims, haha)
Breakpoint it. See what blocks.
Winterdyne Solutions Ltd is recruiting - this thread for details!
Well I got it working. All I did was make a from structure for the client and put it in the from parameter of recvfrom and it works. I didn't think you absolutely needed that parameter but I guess you do.
Artist 1st - Programmer 2nd(I'll get some material linked here sometime to support these claims, haha)

This topic is closed to new replies.

Advertisement