Search code examples
cwinsock

Winsock programming connecting to a public ip


I am trying to connect to my pc publicly from another computer and it returns 10060 error code from the connect function.

When I bind the server with inet_addr("127.0.0.1") from the local machine and connect with a client with that it works.

I have tried to connect with the server's public ip with the same client code down below, it return 10060 can anyone help?

server

#include<winsock2.h>

int main(){
    WSADATA ws;
    SOCKET s, newSocket;
    struct sockaddr_in server, client;
    int c;

    if(WSAStartup(MAKEWORD(2,2), &ws) != 0){
        puts("error wsastartup");
        printf("wsa error at %d", GetLastError());
    }

    if((s=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET){

        printf("socket error at %d", GetLastError());
    }

    server.sin_addr.s_addr = inet_addr("127.0.0.1");
    server.sin_port = htons(8888);
    server.sin_family = AF_INET;

    if(bind(s, (struct sockaddr*)&server, sizeof(server)) == SOCKET_ERROR){
        printf("socket error at %d", GetLastError());
    }else{
        puts("bind done");
    }

    listen(s, 3);
    puts("Waiting for incoming connections");

    c = sizeof(struct sockaddr_in);

    char *message = "hello client i got ur message";    

    while((newSocket = accept(s, (struct sockaddr*) &client, &c)) != INVALID_SOCKET){
        puts("connection accepted");
        send(newSocket, message, strlen(message), 0);
    }

    if(newSocket == INVALID_SOCKET){
        printf("accept failed iwth the code %d", GetLastError());
        return 1;
    }

    getchar();

    closesocket(s);
    WSACleanup();
    return 0;
}

this is the client

#include <winsock2.h>

int main(){

    WSADATA ws;
    SOCKET s;
    struct sockaddr_in server;
    char *message = "hello this is a message";

    if(WSAStartup(MAKEWORD(2,2 ), &ws) != 0){
        printf("wsa error at %d", GetLastError());
    }else{
        puts("wsa done");
    }

    if((s = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET){
        printf("invalid socket at %d", GetLastError());
    }

    server.sin_family = AF_INET;
    server.sin_addr.s_addr = inet_addr("127.0.0.1");
    server.sin_port = htons(8888);

    if(connect(s, (struct sockaddr*)&server, sizeof(server)) < 0){
        printf("connection err %d", GetLastError());
    }else{
        puts("connected");
    }
    return 0;
}

Solution

  • The issue is with your server. You are binding it to 127.0.0.1. This means your server will only bind to the loopback interface, so only clients running on the same machine as the server will be able to connect to the server using this same interface.

    If you want your server to accept clients from a public network interface, you have to bind to that interface's IP instead:

    server.sin_addr.s_addr = inet_addr("<IP belonging to the public interface>");
    

    Or, you can bind your server to all available network interfaces:

    server.sin_addr.s_addr = inet_addr("0.0.0.0");
    

    Or:

    server.sin_addr.s_addr = INADDR_ANY;
    

    Note that you can only bind to IP(s) that belong to the machine that the server is running on. If the public IP the client is trying to connect to belongs to a NAT/router, you must bind the server to its local LAN IP that is connected to the NAT/router, and then set up port forwarding on the NAT/router to forward packets from an open port on the NAT/router's public IP to the listening port on the server's LAN IP. If the NAT/router supports uPNP, your server can setup the port forwarding programmably. Otherwise, the NAT/router's admin has to setup the forwarding manually.