windows tcp socket error 10045 - c

I'm trying to create a server client so I can have a better understanding of how they work, however I'm having an issue, whenever I make the listen() call windows gives me an error with the code 10045, I looked it up and it seems to be because the operation is not supported, however I'm confused as to why this is happening because from what I understand the listen() call should work on tcp sockets. Here's the source code for how I'm initializing the socket
WSADATA wsaData;
WSAStartup(MAKEWORD(2,2), &wsaData);
int sockfd, n;
struct addrinfo hints, *servinfo;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_protocol = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
if((n = getaddrinfo(NULL, argv[1], &hints, &servinfo)) != 0){
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(n));
return EXIT_FAILURE;
}
if((sockfd = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol)) < 0){
fprintf(stderr, "%d\n", WSAGetLastError());
perror("socket");
return EXIT_FAILURE;
}
if((n = bind(sockfd, servinfo->ai_addr, servinfo->ai_addrlen)) == -1){
fprintf(stderr, "%d\n", WSAGetLastError());
perror("bind");
return EXIT_FAILURE;
}
if(listen(sockfd, 1) == -1){ //error
fprintf(stderr, "%d\n", WSAGetLastError());
perror("listen");
return EXIT_FAILURE;
}

You set the wrong protocol/socket type:
hints.ai_protocol = SOCK_STREAM;
If you read the addrinfo structure reference the socket type should be in the ai_socktype field:
hints.ai_socktype = SOCK_STREAM;
Since you set the wrong ai_protocol the socket call will create the wrong type of socket for you, and the listen call will fail.
The lesson here is to always read the documentation.

Related

How can I connect with my friend over the web using winsocket2?

This question is similar to others but I found so much information I am not sure what is important and what not anymore.
What I am doing is a simple chat program where I create the server and my friend and I both have one socket to send messages through.
Server side:
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <stdbool.h>
SOCKET start_server(void)
{
INT iResult;
SOCKET sock;
struct addrinfo *result = NULL;
struct addrinfo hints;
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
// Resolve the server address and port
iResult = getaddrinfo("192.168.70.3", "666", &hints, &result);
if(iResult)
{
printf("> error: getaddrinfo failed (error code: %d)\n", iResult);
return INVALID_SOCKET;
}
// Create a SOCKET for connecting to server
sock = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if(sock == INVALID_SOCKET)
{
printf("> error: socket failed (error code: %d)\n", WSAGetLastError());
freeaddrinfo(result);
return INVALID_SOCKET;
}
// Setup the TCP listening socket
iResult = bind(sock, result->ai_addr, (int) result->ai_addrlen);
if(iResult == SOCKET_ERROR)
{
printf("> error: bind failed (error code: %d)\n", WSAGetLastError());
freeaddrinfo(result);
closesocket(sock);
return INVALID_SOCKET;
}
freeaddrinfo(result);
return sock;
}
int main(int argc, char **argv)
{
char buf[1024];
SOCKET serverSock;
SOCKET socks[2];
WSADATA wsaData;
INT iRetval;
if((iRetval = WSAStartup(MAKEWORD(2, 2), &wsaData)))
{
printf("> error: Startup failed(error code: 0xF0%x)\n", iRetval);
return 0xFF;
}
printf("> Connecting to server...\n");
serverSock = start_server();
printf("> Connected to server...\n");
printf("> Listening for connections..\n");
listen(serverSock, 0);
socks[0] = accept(serverSock, NULL, NULL);
printf("> One client connected\n");
listen(serverSock, 0);
socks[1] = accept(serverSock, NULL, NULL);
printf("> Another client connected\n");
while(1)
{
if(recv(socks[0], buf, sizeof(buf), 0) > 0)
{
send(socks[1], buf, strlen(buf) + 1, 0);
}
if(recv(socks[1], buf, sizeof(buf), 0) > 0)
{
send(socks[0], buf, strlen(buf) + 1, 0);
}
Sleep(10);
}
return 0;
}
Client side:
SOCKET user_connect(void)
{
SOCKET sock = INVALID_SOCKET;
struct addrinfo *result = NULL, *ptr = NULL, hints;
int iResult;
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
iResult = getaddrinfo("public_ip_address", "666", &hints, &result);
if(iResult)
{
printf("> error: getaddrinfo failed (error code: %d)\n", iResult);
return INVALID_SOCKET;
}
// Attempt to connect to an address until one succeeds
for(ptr = result; ptr; ptr = ptr->ai_next)
{
// Create a SOCKET for connecting to server
sock = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if(sock == INVALID_SOCKET)
{
printf("> error: socket failed (error code: %d)\n", WSAGetLastError());
return INVALID_SOCKET;
}
// Connect to server.
printf("> Trying to connect to: cannon name[%s], family[%d], protocol[%d], socket type[%d], flags[%d]\n", ptr->ai_canonname, ptr->ai_family, ptr->ai_protocol, ptr->ai_socktype, ptr->ai_flags);
iResult = connect(sock, ptr->ai_addr, (int) ptr->ai_addrlen);
if(iResult == SOCKET_ERROR)
{
closesocket(sock);
sock = INVALID_SOCKET;
continue;
}
break;
}
freeaddrinfo(result);
return sock;
}
The problem is that it fails establishing a connection. Note that it works when I use a local ip address instead of public_ip_address and open each component on my PC only.
So I got my public IP, local IP, even set up a Port Forwarding but I am not sure what gives.
My question is what I am doing wrong and what I need to do to establish a connection.

C Socket code works within LAN but not over WAN? Connection refused?

I've been working on a connect 4 game that contains both the client and server code in my main function for a TCP connection.I'm unable to connect over the internet. I've tried running my client code on a laptop that isn't on my LAN specifying my LAN's public IP and the desired port number. However,keep getting a connection refused as my perror message when connect fails.
//client code
if(argc == 3){
turn = CLIENT;
int status, client_sockfd;
struct addrinfo hints, *res;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
if((status = getaddrinfo(argv[1], argv[2], &hints, &res)) != 0){
fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
exit(1);
}
if((client_sockfd = socket(res -> ai_family, res -> ai_socktype, res -> ai_protocol)) == -1){
fprintf(stderr, "socket creation error: %s\n", gai_strerror(client_sockfd));
exit(1);
}
if((connect(client_sockfd, res -> ai_addr, res -> ai_addrlen)) == -1){
perror("cannot connect");
exit(1);
}
freeaddrinfo(res); //free res structure
//Start of Game: Client
recv(client_sockfd, player1, 25, 0);
printf("Player 2, enter your name:\n");
fgets(player2, sizeof(player2), stdin);
send(client_sockfd, player2, 25, 0);
sock = client_sockfd;
}
//server network code
else{
turn = SERVER;
int server_sockfd;
printf("Setting up the game\n");
//server port
if(argc == 2)
myport = argv[1];
else
myport = "12345";
int status, sock_fd;
int opt = 1;
struct addrinfo hints, *res;
struct sockaddr_storage their_addr;
socklen_t addr_size;
memset(&hints, 0, sizeof(hints)); //make sure hints is empty
hints.ai_family = AF_UNSPEC; //ipv6 or ipv4 doesn't matter
hints.ai_socktype = SOCK_STREAM; //require TCP stream sockets
hints.ai_flags = AI_PASSIVE;
//load res adderinfo struct
if((status = getaddrinfo(NULL, myport, &hints, &res)) != 0){
fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
exit(1);
}
//create socket with res
if((sock_fd = socket(res -> ai_family, res -> ai_socktype, res -> ai_protocol)) == -1){
fprintf(stderr, "socket creation error: %s\n", gai_strerror(sock_fd));
exit(1);
}
//reuseable socket
if(setsockopt(sock_fd,SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1){
perror("setsockopt");
exit(1);
}
//bind socket for use
if((bind(sock_fd, res -> ai_addr, res-> ai_addrlen)) == -1){
perror("binding fail");
exit(1);
}
//listen with a backlog of 5
listen(sock_fd, 5);
addr_size = sizeof(their_addr);
if((server_sockfd = accept(sock_fd, (struct sockaddr *)&their_addr, &addr_size)) == -1){
perror("accepting failure");
exit(1);
}
freeaddrinfo(res); //free res structure
//Start of Game: Server
printf("Player 1, please enter your name:\n");
fgets(player1, sizeof(player1), stdin);
send(server_sockfd, player1, 25, 0);
recv(server_sockfd, player2, 25, 0);
sock = server_sockfd;
}
Any thoughts? From my understanding, as the client, my packet should reach the server's gateway and NAT should use my destination port to redirect my messages to the server?

listen(): invalid argument

Trying to create a server-client application, and I'm having quite a bit of trouble setting up the connection on the server-side. After setting up the socket, and bind()ing the socket, my listen()-call fails with the error message
listen: Invalid argument
which I get from perror()-ing the case where listen() returns -1.
The synopsis of the program is the following: I use getaddrinfo() to generate a linked list of struct addrinfo's, loop through that until I find one that I can successfully create a socket with, then bind() and finally listen().
The listen() call goes as follows:
if ((status = listen(socket_fd, BACKLOG_SIZE)) == -1) {
perror("listen");
close(socket_fd);
freeaddrinfo(res);
exit(EXIT_FAILURE);
}
To be sure, I've printed the values of socket_fd and BACKLOG_SIZE, turning out to be 3 and 5, respectively. Have been debugging for hours now, and I simply cannot find out where the problem lies. Haven't found anyone with the same issue on stackOverflow, either...
Thank you in advance for any help!
Full program:
int main(int argc, char* argv[]) {
int port_no = server_usage(argc, argv);
ready_connection(port_no);
/* Synopsis:
getaddrinfo()
socket()
bind()
listen()
accept()
*/
int socket_fd = setup_socket(NULL, port_no);
struct sockaddr_storage their_addr;
socklen_t addr_size = sizeof(their_addr);
int new_fd = 0;
// Allow reuse of sockets
int activate=1;
setsockopt(socket_fd, IPPROTO_TCP, TCP_NODELAY, &activate, sizeof(int));
if ((status = bind(socket_fd, res->ai_addr, res->ai_addrlen)) == -1) {
perror("bind");
exit(EXIT_FAILURE);
}
if ((status = connect(socket_fd, res->ai_addr, res->ai_addrlen)) == -1) {
perror("connect");
close(socket_fd);
freeaddrinfo(res); // free the linked-list
exit(EXIT_FAILURE);
}
if ((status = listen(socket_fd, BACKLOG_SIZE)) == -1) {
perror("listen");
close(socket_fd);
freeaddrinfo(res); // free the linked-list
exit(EXIT_FAILURE);
}
if ((new_fd == accept(socket_fd, (struct sockaddr *)&their_addr, &addr_size)) == -1) {
perror("accept");
exit(EXIT_FAILURE);
}
char buffer[BUFSIZE];
recv(new_fd, buffer, BUFSIZE, 0);
close(socket_fd);
close(new_fd);
freeaddrinfo(res); // free the linked-list
return 0;
}
setup_socket()-function:
int setup_socket(char* hostname, int port_no) {
// hints is mask struct, p is loop variable
struct addrinfo hints, *p;
memset(&hints, 0, sizeof hints); // make sure the struct is empty
// TODO IPv6-support?
hints.ai_family = AF_INET; // only IPv4 supported
hints.ai_socktype = SOCK_STREAM; // TCP stream sockets
hints.ai_flags = AI_PASSIVE; // fill in my IP for me
char port_str[6]; // max port size is 5 digits + 0-byte
memset(port_str, 0, 6);
sprintf(port_str, "%d", port_no);
if ((status = getaddrinfo(hostname, port_str, &hints, &res)) == -1) {
fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
exit(EXIT_FAILURE);
}
int socket_fd = 0;
for (p = res; p != NULL; p = p->ai_next) {
if ((socket_fd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
perror("socket");
exit(EXIT_FAILURE);
}
}
if (socket_fd == 0) {
errno = ENOTSOCK;
perror("no socket");
exit(EXIT_FAILURE);
}
return socket_fd;
}
You cannot connect(), then listen() on the same socket. Lose the connect().

Invalid Argument: connect() C socket programming

I'm working on a C program that creates a connection between a client and server. When I run connect on the socket I've already created I keep getting an error that I'm passing an invalid argument.
Any help would be awesome!
void client(char* ipAddress, char* serverPort){
//code for setting up the IP address and socket information from Beej's Guide to Network Programming
//Need to setup two addrinfo structs. One for the client and one for the server that the connection will be going to
int status;
//client addrinfo
struct addrinfo hints, *res; // will point to the results
//server addrinfo
int socketDescriptor;
int addressLength;
memset(&hints, 0, sizeof hints); // make sure the struct is empty
hints.ai_family = AF_UNSPEC; // don't care IPv4 or IPv6
hints.ai_socktype = SOCK_STREAM; // TCP stream sockets
hints.ai_flags = AI_PASSIVE; // fill in my IP for me
//setup client socket
if ((status = getaddrinfo(ipAddress, serverPort, &hints, &res)) != 0) {
printf("%s \n", "This error above");
fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
exit(1);
}
if((socketDescriptor = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) ==-1){
perror("client: socket");
}
addressLength = sizeof hints;
if(connect(socketDescriptor, res->ai_addr, addressLength)==-1){
close(socketDescriptor);
perror("client: connect");
}
}
Apart from some inconsistent variable names in your code,
this seems to be wrong:
addressLength = sizeof hints;
if(connect(socketDescriptor, res->ai_addr, addressLength)==-1) ...
It should be
if(connect(socketDescriptor, res->ai_addr, res->ai_addrlen)==-1) ...

Error receiving in UDP: Connection refused

I am trying to send a string HI to a server over UDP in a particular port and then to receive a response. However, after I try to get the response using recvfrom() I was stuck in blocking state. I tried using connected UDP but I got:
Error receiving in UDP: Connection refused
What could be the reasons for this? The server is not under my control, but I do know its working fine.
I have added the code
int sockfdudp;
char bufudp[MAXDATASIZE], port[6];
struct addrinfo hints, *servinfo, *p;
struct sockaddr_storage addr;
int rv;
char s[INET6_ADDRSTRLEN];
int bytes_recv, bytes_sent;
socklen_t len;
scanf("%s",port);
printf("UDP Port: %s \n", port);
// Start connecting to datagram server
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
if ((rv = getaddrinfo(SERVER_NAME, port, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
return 1;
}
// loop through all the results and make a socket
for(p = servinfo; p != NULL; p = p->ai_next) {
if ((sockfdudp = socket(p->ai_family, p->ai_socktype,
p->ai_protocol)) == -1) {
perror("Creating datagram socket");
continue;
}
if (connect(sockfdudp, p->ai_addr, p->ai_addrlen) == -1) {
close(sockfdudp);
perror("Connecting stream socket");
continue;
}
break;
}
if (p == NULL) {
fprintf(stderr, "ClientUDP: failed to bind socket\n");
return 2;
}
freeaddrinfo(servinfo);
if ((bytes_sent = sendto(sockfdudp, UDP_MSG, strlen(UDP_MSG), 0, p->ai_addr, p->ai_addrlen)) == -1) {
perror("ClientUDP: Error sending data");
exit(1);
}
printf("Data %s sent\n", UDP_MSG );
len = sizeof(struct sockaddr_storage);
if ((bytes_recv = recvfrom(sockfdudp, bufudp, MAXDATASIZE-1, 0,(struct sockaddr*)&addr, &len)) == -1) {
perror("Error receiving in UDP");
exit(1);
}
printf("Bytes recv %d\n", bytes_recv);
bufudp[bytes_recv] = '\0';
printf("ClientUDP: Received\n %s \n",bufudp );
close(sockfdudp);
return 0;
Chances are your're sending something to a server who does not listen on that particular port.
That would cause an icmp message to be sent back , and your next recvfrom will return an error in the case where you connect the socket.
Check with tcpdump or wireshark what's going on on the wire.
My guess would be that your ip address is bad somehow, or the port is already in use somehow. UDP is connectionless, so there really isn't any "connection" to fail.

Resources