1

I'll keep it simple.
Code:

    #include "stdafx.h"
    #include <winsock2.h>
    #include <conio.h>
    #include <iostream>
    #include <stdio.h>
    #include <tchar.h>

int _tmain(int argc, _TCHAR* argv[])
{
    WSADATA wsadata;
    int error = WSAStartup(0x0202, &wsadata);
    if(error) printf("WinSock error!");
    SOCKET server;
    struct sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(5657);
    server_addr.sin_addr.s_addr = htonl (INADDR_ANY); 
    server = socket(AF_INET, SOCK_STREAM, 0);
    if (server == INVALID_SOCKET) printf("INVALID SOCKET!");
    error = bind(server, (LPSOCKADDR)&server_addr, sizeof(server_addr));
    if(error) printf("Connect Error!");
    listen(server, SOMAXCONN);
    printf("SERVER ESTABLISHED! LISTENING...\n");
    sockaddr_in client_addr;
    SOCKET client;
    client = accept(server, (struct sockaddr*)&client_addr, (int *)sizeof(client_addr));
    if(client==INVALID_SOCKET) printf("INVALID SOCKET!\n");
    printf("A CLIENT!");
    closesocket(server);
    WSACleanup();
    getch();
    return 0;
}


But what I get is:

SERVER ESTABLISHED! LISTENING... INVALID SOCKET! A CLIENT!

I've done sockets in C# and I guess the server is supposed to listen and wait for a client, and whenever a client requests for a connection, the server should accept it, but the server accepts a socket without waiting, and this accepted socket is invalid, too! Why does this happen and how can I solve it?

dsynkd
  • 1,999
  • 4
  • 26
  • 40

3 Answers3

4

This:

(int *)sizeof(client_addr)

is wrong, you're casting the size to a pointer.

socklen_t client_addr_len = sizeof(client_addr);
client = accept(server, (struct sockaddr*)&client_addr, &client_addr_len);
James M
  • 18,506
  • 3
  • 48
  • 56
  • Damn! Was typing this :) +1 for beating me –  Jan 19 '12 at 17:03
  • Hi. Thanks but I found out that socklen_t is undefined! Any alternative structs??? – dsynkd Jan 19 '12 at 21:19
  • Looks like `int` should be fine: http://msdn.microsoft.com/en-us/library/windows/desktop/ms737526%28v=vs.85%29.aspx (just replace `socklen_t` with `int`, _not_ `int *`). – James M Jan 19 '12 at 21:22
1
(int *)sizeof(client_addr)

You're casting the client_addr size into an int*, so you have a pointer that points to an address which is equal to the size of your client_addr.

You need to do:

socklen_t clntAddrLen = sizeof(client_addr);
client = accept(server, (struct sockaddr*)&client_addr, &clntAddrLen);

This way is different because you have a variable of type socklen_t which holds the size of your client_addr. You're then getting a pointer (with &) that points to the memory address where that number is contained which is what you want.

John Humphreys
  • 37,047
  • 37
  • 155
  • 255
  • Hi. Thanks but I found out that socklen_t is undefined! Any alternative structs??? I'm using Visual Studio 2010. – dsynkd Jan 19 '12 at 21:21
  • The socklen_t type is defined inside of WS2tcpip.h in windows. This is not transitively included from winsock2.h (AFAICT). You'll need to include WS2tcpip.h manually in order to use the socklen_t type. - taken from http://stackoverflow.com/a/4454036/857994 – John Humphreys Jan 19 '12 at 21:35
1

The problem may be that accept will attempt to write to the last argument provided to it.

Change to:

int client_addr_size = sizeof(client_addr);
client = accept(server, (struct sockaddr*)&client_addr, &client_addr_size);

Checking the value of WSAGetLastError will provide the reason for failure.

hmjd
  • 120,187
  • 20
  • 207
  • 252