views:

153

answers:

3

Hi,

I'm having the weirdest problem causing me headaches. Consider the following code:

// Create and bind socket
 std::map<Connection, bool> clients;
 unsigned short port=6222;
 struct sockaddr_in local_address, from_address;
 int result;
 char buffer[10000];
 SOCKET receive_socket;
 local_address.sin_family = AF_INET;
 local_address.sin_addr.s_addr = INADDR_ANY;
 local_address.sin_port = htons(port);
 receive_socket = socket(AF_INET,SOCK_DGRAM,0);

What's happening is receive_socket is not binding, I get SOCKET_ERROR. When I debug the program and check receive_socket, it appears to just be garbled crap. I put a breakpoint on the 'std::map' line. When I step into each line of the above code, the debug cursor jumps straight from the 'unsigned short port' line to the first 'local_address.sin' line, even though I am using step into (F11), it does not stop at struct, int, char or SOCKET lines, it jumps straight over them.

At this point I hover my mouse over local_address, from_address, result, buffer and receive_socket. They are all full of garbled crap. Is this because I have not defined these variables yet? I've also noticed that when I reach the bottom of the above code, local_address.sin_port is set to 19992, but it should be 6222?

Edit: here is my binding code which is failing because the if statement is true:

if(bind( receive_socket, (SOCKADDR*) &local_address, sizeof(local_address)) == SOCKET_ERROR) 
    {
        closesocket(receive_socket);
        return 1;
    }
A: 

Try changing SOCK_DGRAM to SOCK_STREAM

According to MSDN,

SOCK_STREAM - A socket type that provides sequenced, reliable, two-way, connection-based byte streams with an OOB data transmission mechanism. This socket type uses the Transmission Control Protocol (TCP) for the Internet address family (AF_INET or AF_INET6).

SOCK_DGRAM - A socket type that supports datagrams, which are connectionless, unreliable buffers of a fixed (typically small) maximum length. This socket type uses the User Datagram Protocol (UDP) for the Internet address family (AF_INET or AF_INET6).

And as far as the port goes...

local_address.sin_port is set to 19992, but it should be 6222?

htons converts a port number in host byte order to network byte order (see here)

George Edison
Ok that makes sense about htons. I tried your suggestion changing SOCK_DGRAM to SOCK_STREAM but it still won't bind. Here's my binding code:if(bind( receive_socket, (SOCKADDR*) return 1; }
Ash85
Also, I have to use UDP which is why it's SOCK_DGRAM.
Ash85
Ah. Forget that part :) I see you figured it out anyway.
George Edison
A: 
local_address.sin_port = htons(port);

I found that rather weird. Also, why htons() the port? That makes no sense. Couldn't you just use getaddrinfo() or something like that, or does winsock require to manually fill in info?

Maister
+1  A: 

I figured out the answer! The problem was I was not calling WSAStartup anywhere in my program. The following code at the beginning fixed it:

WSADATA wsaData;
    if(WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) 
    {
        return 1; 
    }

I found this out by getting the error number from WSAGetLastError() and looking it up on msdn.

Ash85