Winsock and UDP (client/server app)

Started by
18 comments, last by hplus0603 13 years, 6 months ago
Hello!

I'm currently working on an airhockey game, where you can host/connect. I'm using TCP for connecting to the host, and I'm going to use UDP for sending game data packets. Everything has gone great so far, but now I'm stuck in the UDP part. Currently the server is creating a UDP socket and binding it to a specific port. The client creates a udp socket aswell. The problem here is, how is the client going to recieve packets from the server? the recvfrom(...) takes a bound socket as first argument. The only bound udp socket that is created, is by the server. Should I send the server udp socket descriptor to the client using tcp? That is the only thing I can think of, I've searched everywhere, looked for tutorials, but nothing has worked... Any kind of help is appreciated.

Mufflot
Advertisement
The socket doesn't need to be bound, you can use a socket freshly created from socket().
You can't receive UDP data on a TCP socket, or vice-versa.

However, UDP and TCP are completely separate, you'll probably run into firewall issues if the clients try to recvfrom() the server without that port open.
What would be better would be to have the clients also open a UDP connection to the server when the TCP connection is established. Then you can use the UDP socket to sendto() / recvfrom() the server
Thanks for the quick answer.

Quote:Original post by Evil Steve
The socket doesn't need to be bound, you can use a socket freshly created from socket().


Ah great.

Quote:Original post by Evil Steve
What would be better would be to have the clients also open a UDP connection to the server when the TCP connection is established. Then you can use the UDP socket to sendto() / recvfrom() the server


Ok, I'm not sure I understand completely. Do you mean that when the the TCP connection is established. The client should use connect(...), using the UDP socket descriptor as argument, to establish a UDP connection to the server?

Mufflot

Quote:Original post by Mufflot
Ok, I'm not sure I understand completely. Do you mean that when the the TCP connection is established. The client should use connect(...), using the UDP socket descriptor as argument, to establish a UDP connection to the server?
Yep - the client needs to make an outgoing connection for the firewall (router, etc) to allow traffic from the server to reach the client. That means making a connect() call to connect to the server and bind the socket, or to call sendto() with the server's address in the sockaddr, which will also bind the socket.
Quote:Original post by Evil Steve
Yep - the client needs to make an outgoing connection for the firewall (router, etc) to allow traffic from the server to reach the client. That means making a connect() call to connect to the server and bind the socket, or to call sendto() with the server's address in the sockaddr, which will also bind the socket.


I see, I'm gonna try that out. Very much thanks!

Quote:Original post by Evil Steve
Yep - the client needs to make an outgoing connection for the firewall (router, etc) to allow traffic from the server to reach the client. That means making a connect() call to connect to the server and bind the socket, or to call sendto() with the server's address in the sockaddr, which will also bind the socket.


I think the general term for that is "NAT Punchthrough" You might find some information about that on google. There is also the possibility that both server and client are behind a Router in which case you'd have to introduce a third party to make connection possible.
Quote:Original post by Madhed
I think the general term for that is "NAT Punchthrough" You might find some information about that on google. There is also the possibility that both server and client are behind a Router in which case you'd have to introduce a third party to make connection possible.


Okay. So using 'sendto' might be better then perhaps?

I got my socket waiting in the 'recvfrom' call atleast, which is progress compared to the last time I tried when I got an 'invalid socket' error.
I've got an other issue now. I want the server to send packets to the client, the packets doesn't seem to arrive to the client. Here is my current implementation. I really can't see why the packets doesn't arrive.

Server
udpSocket.SendTo(    udpSocket.GetDescriptor(),     PortUDP, // port the socket is bound to    clientIpAddress.c_str(),    "heja",    4);voidSocket::SendTo(    int socketDescriptor,     int port,     const char* ip,     const char* data,     unsigned int size){    ULONG internetAddress = inet_addr(ip);    sockaddr_in socketAddress;    GetSocketAddress(socketAddress, internetAddress, port);    sendto(        socketDescriptor,        data,        size,        0,        (SOCKADDR*)&socketAddress,        sizeof(socketAddress));}voidSocket::GetSocketAddress(sockaddr_in& out, ULONG internetAddress, int port) const{    out.sin_family = AF_INET;    out.sin_addr.S_un.S_addr = internetAddress;    out.sin_port = htons((u_short)port);}


Client
if (udpSocket.ReceiveFrom(    udpSocket.GetDescriptor(),    PortUDP,    serverIpAddress.c_str(),    buffer)){    // packet recieved, get data from it, using GamePacket    int breakHere = 0;breakHere;}boolSocket::ReceiveFrom(int socketDescriptor, int /*port*/, const char* /*ip*/, std::string& out){    SOCKADDR from;    char inbuffer[256];    int len = sizeof(SOCKADDR);    memset(inbuffer, '\0', 256);    int numberOfBytes = recvfrom(        socketDescriptor,         inbuffer,         sizeof(inbuffer)-1,         0,         &from,         &len);    if (numberOfBytes <= 0)    {	return false;    }    out = inbuffer;    return true;}



Are client and server running on the same machine, on the same local network or are the two only communicating over the internet?
same local network and over the internet should be possible.
I mean right now, with the example you gave. :) Could you post some more code snippets. For example the initialization of portUDP?

This topic is closed to new replies.

Advertisement