Reputation: 2145
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?
Upvotes: 1
Views: 922
Reputation: 121961
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.
Upvotes: 1
Reputation: 39254
(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.
Upvotes: 1
Reputation: 16718
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);
Upvotes: 4