socket fail, but telnet can connect

Mar 20, 2012 at 8:16pm
my problem is that I can't connect two comps through socket (windows xp and windows7) although the server created with socket is listening and I can telnet it. It receives then information and does what should be done, but if I run the corresponding socket client I get error 10061. Moreover I am behind firewall - these two comps are running within my LAN, the windows firewalls are turned off,

comp1 [client]: 192.168.1.2 port 12345

comp2 [server]: 192.168.1.5 port 12345

router: 192.168.1.1

Maybe port forwarding could help? But most important for me is to answer why Sockets fail if telnet works fine.

client:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
 int main(){
        // Initialize Winsock.
        WSADATA wsaData;
        int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
        if (iResult != NO_ERROR)
             printf("Client: Error at WSAStartup().\n");
        else
             printf("Client: WSAStartup() is OK.\n");
        // Create a socket.
        SOCKET m_socket;
        m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

        if (m_socket == INVALID_SOCKET){
            printf("Client: socket() - Error at socket(): %ld\n", WSAGetLastError());
            WSACleanup();
            return 7;
        }else
           printf("Client: socket() is OK.\n");

        // Connect to a server.
        sockaddr_in clientService;

        clientService.sin_family = AF_INET;
        //clientService.sin_addr.s_addr = inet_addr("77.64.240.156");
        clientService.sin_addr.s_addr = inet_addr("192.168.1.5");
        //clientService.sin_addr.s_addr = inet_addr("87.207.222.5");
        clientService.sin_port = htons(12345);

        if (connect(m_socket, (SOCKADDR*)&clientService, sizeof(clientService)) == SOCKET_ERROR){
            printf("Client: connect() - Failed to connect.\n");
            wprintf(L"connect function failed with error: %ld\n", WSAGetLastError());
            iResult = closesocket(m_socket);
            if (iResult == SOCKET_ERROR)
            wprintf(L"closesocket function failed with error: %ld\n", WSAGetLastError());
            WSACleanup();
            return 6;
        }

        // Send and receive data
        int bytesSent;
        int bytesRecv = SOCKET_ERROR;
        // Be careful with the array bound, provide some checking mechanism
        char sendbuf[200] = "Client: Sending some test string to server...";
        char recvbuf[200] = "";

        bytesSent = send(m_socket, sendbuf, strlen(sendbuf), 0);
        printf("Client: send() - Bytes Sent: %ld\n", bytesSent);

        while(bytesRecv == SOCKET_ERROR){
            bytesRecv = recv(m_socket, recvbuf, 32, 0);
            if (bytesRecv == 0 || bytesRecv == WSAECONNRESET){
                printf("Client: Connection Closed.\n");
                break;
            }else
                printf("Client: recv() is OK.\n");

            if (bytesRecv < 0)
                return 0;
            else
                printf("Client: Bytes received - %ld.\n", bytesRecv);
        }
        system("pause");
        return 0;
    }


server:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
int main(){
WORD wVersionRequested;
WSADATA wsaData={0};
int wsaerr;

// Using MAKEWORD macro, Winsock version request 2.2
wVersionRequested = MAKEWORD(2, 2);
wsaerr = WSAStartup(wVersionRequested, &wsaData);
if (wsaerr != 0){
    /* Tell the user that we could not find a usable WinSock DLL.*/
    printf("Server: The Winsock dll not found!\n");
    return 0;
}else{
       printf("Server: The Winsock dll found!\n");
       printf("Server: The status: %s.\n", wsaData.szSystemStatus);
}

/* Confirm that the WinSock DLL supports 2.2.*/
/* Note that if the DLL supports versions greater    */
/* than 2.2 in addition to 2.2, it will still return */
/* 2.2 in wVersion since that is the version we      */
/* requested.                                        */
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2 ){
/* Tell the user that we could not find a usable WinSock DLL.*/
printf("Server: The dll do not support the Winsock version %u.%u!\n", LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion));
       WSACleanup();
       return 0;
}else{
       printf("Server: The dll supports the Winsock version %u.%u!\n", LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion));
       printf("Server: The highest version this dll can support: %u.%u\n", LOBYTE(wsaData.wHighVersion), HIBYTE(wsaData.wHighVersion));
}
//////////Create a socket////////////////////////
//Create a SOCKET object called m_socket.
SOCKET m_socket;
// Call the socket function and return its value to the m_socket variable.
// For this application, use the Internet address family, streaming sockets, and the TCP/IP protocol.
// using AF_INET family, TCP socket type and protocol of the AF_INET - IPv4
m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

// Check for errors to ensure that the socket is a valid socket.
if (m_socket == INVALID_SOCKET){
    printf("Server: Error at socket(): %ld\n", WSAGetLastError());
    WSACleanup();
    //return 0;
}else{
    printf("Server: socket() is OK!\n");
}

////////////////bind//////////////////////////////
// Create a sockaddr_in object and set its values.
sockaddr_in service;

// AF_INET is the Internet address family.
service.sin_family = AF_INET;
// "127.0.0.1" is the local IP address to which the socket will be bound.
service.sin_addr.s_addr = htons(INADDR_ANY);//inet_addr("127.0.0.1");//htons(INADDR_ANY); //inet_addr("192.168.1.2");
// 55555 is the port number to which the socket will be bound.
// using the htons for big-endian
service.sin_port = htons(12345);

// Call the bind function, passing the created socket and the sockaddr_in structure as parameters.
// Check for general errors.
if (bind(m_socket, (SOCKADDR*)&service, sizeof(service)) == SOCKET_ERROR){
    printf("Server: bind() failed: %ld.\n", WSAGetLastError());
    closesocket(m_socket);
    //return 0;
}else{
    printf("Server: bind() is OK!\n");
}
// Call the listen function, passing the created socket and the maximum number of allowed
// connections to accept as parameters. Check for general errors.
if (listen(m_socket, 1) == SOCKET_ERROR)
       printf("Server: listen(): Error listening on socket %ld.\n", WSAGetLastError());
else{
    printf("Server: listen() is OK, I'm waiting for connections...\n");
}

// Create a temporary SOCKET object called AcceptSocket for accepting connections.
SOCKET AcceptSocket;

// Create a continuous loop that checks for connections requests. If a connection
// request occurs, call the accept function to handle the request.
printf("Server: Waiting for a client to connect...\n");
printf("***Hint: Server is ready...run your client program...***\n");
// Do some verification...
while (1){
    AcceptSocket = SOCKET_ERROR;

      while (AcceptSocket == SOCKET_ERROR){
        AcceptSocket = accept(m_socket, NULL, NULL);
       }
   // else, accept the connection...  note: now it is wrong implementation !!!!!!!! !! !! (only 1 char)
   // When the client connection has been accepted, transfer control from the
   // temporary socket to the original socket and stop checking for new connections.
    printf("Server: Client Connected! Mammamija. \n");
    m_socket = AcceptSocket;
    char recvBuf[200]="";
    char * rc=recvBuf;
    int bytesRecv=recv(m_socket,recvBuf,64,0);

    if(bytesRecv==0 || bytesRecv==WSAECONNRESET){
        cout<<"server: connection closed.\n";
        }else{
            cout<<"server: recv() is OK.\n";
            if(bytesRecv<0){
                return 0;
                }else{
                    printf("server: bytes received: %ld.\n",recvBuf);
            }
    }

the output from client:

PS C:\Users\Piter\documents\vs2010\projects\client_socket\debug> ./client_socket.exe
Client: WSAStartup() is OK.
Client: socket() is OK.
Client: connect() - Failed to connect.
connect function failed with error: 10061
PS C:\Users\Piter\documents\vs2010\projects\client_socket\debug> ipconfig
Mar 20, 2012 at 8:17pm
when server is running telnet 192.168.1.5 12345 works fine, but this socket client gets error 10061

I have created listening socket using netcat and powershell (not sure in a proper way):

1
2
3
4
PS C:\netcat> ./nc.exe -v -l -p 12345
listening on [any] 12345 ...
Warning: forward host lookup failed for cf16.chello.pl: h_errno 11001: HOST_NOT
connect to [192.168.1.2] from cf16.chello.pl [192.168.1.2] 4473: HOST_NOT_FOUND


the third and fourth lines are what happened when created client in another powershell by:

PS C:\netcat> ./nc.exe 192.168.1.2 12345

ok. when forced netstat not to resolve but use IP given, now it connects:

1
2
3
PS C:\netcat> ./nc.exe -n -v -l -p 12345
listening on [any] 12345 ...
connect to [192.168.1.2] from (UNKNOWN) [192.168.1.2] 4622


but my C++ still returns error 10061. any ideas? please help :D
Last edited on Mar 20, 2012 at 9:36pm
Mar 20, 2012 at 11:08pm
If I had to put money on it, I'd say it's a firewall issue on the server machine.

You're not clear on where you run telnet.

It seems you're running netcat on the server machine, and the server is listening to all interfaces. So that doesn't exercise the 192.168.1.5 interface as you're going in thru the 127.0.0.1 interface.

The client cannot connect to 192.168.1.5:12345. See the error code explanation below.

http://msdn.microsoft.com/en-us/library/aa924071.aspx
10061
WSAECONNREFUSED
Connection refused. No connection could be made because the target machine actively refused it. This usually results from trying to connect to a service that is inactive on the foreign host — that is, one with no server application running.

A few comments on the code.
The client doesn't close the socket and really should call WSACleanup even though you don't have to.
The server has a serious error. The socket it listens on is different from the client connection. You overwrite the listening socket when a client connects.
Mar 21, 2012 at 10:48pm
why you claim that sockets are different? both are created with specification:
m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
family=AF_INET;
port = htons(12345);

firewalls are both turned off. client cannot connect even when server is running on the same machine
Last edited on Mar 21, 2012 at 10:53pm
Mar 22, 2012 at 11:03am
why you claim that sockets are different?
I think you've misunderstood what I've said. Please reread what I said.

I've compiled your code and the client connects to the server once port 12345 was opened. Of course it stops because of the problems I described plus one more.

I still believe you have a firewall issue.
Mar 22, 2012 at 3:41pm

here is what you said:
The socket it listens on is different from the client connection. You overwrite the listening socket when a client connects.


you said socket is different from connection. was it sth you want to express?
if yes, I don't understand, please explain, and give an advice what to do, thx.
Mar 22, 2012 at 7:11pm
Ok, here we go.

The server listens for incomming connections on a socket that's created (with socket()), bound to an address (with bind()), set to listen (with listen()) and accepts a connection (with accept()).

However, the socket that accept() returns is a connection to a client. And when accept() returns, you have two sockets to deal with, the listening socket that allows clients to connect in, and the socket returned from accept() that is the connection to a client that connected in.

The listening socket should go back to listening for more connections while the client socket should be used to communicate with that client. In a "real" server, there will be a listening socket and possibly many client connections.

A typical client will connect to a server, send a request, read the response and close. The server will see a new client connection when accept() returns, it can read the request, do some work, send the reply and then close that socket.

Back to your code, you create the listening socket with:
1
2
3
m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
bind(m_socket, (SOCKADDR*)&service, sizeof(service))
listen(m_socket, 1)

then you accept new client connections with:
 
AcceptSocket = accept(m_socket, NULL, NULL);

then you overwrite the listening socket with:
 
m_socket = AcceptSocket;

So you no longer have a socket on which to recieve new connections.
Mar 23, 2012 at 9:09am
thank you very much,
this is truely a bug which make my server unable to listen more than one connection - but is this a reason for error 10061 "connection refused" if I try first time, only one client?
no client can connect at all - do you think that removing this bug will be a solution?
Mar 23, 2012 at 10:38am
do you think that removing this bug will be a solution?
No, you have a firewall issue.

Your code connects and sends the first packet on my LAN. I ran the server on Windows XP (had to open the firewall on port 12345) and the client on Mac OS X.

You have to be careful of testing your server from the same computer. Your server code listens to:
 
service.sin_addr.s_addr = htons(INADDR_ANY);
which means listen to ALL interfaces. On a home laptop, that'll be the built-in ethernet connector, the wifi connector and the loopback address.

A local client will probably go in thru the loopback address, making such tests meaningless. You can tell the server to listen on a specific address:
 
service.sin_addr.s_addr = inet_addr("192.168.1.5");

It won't then listen to the loopback address and all local clients will be routed thru the 192.168.1.5 interface stack including the firewall.
Last edited on Mar 23, 2012 at 10:51am
Mar 23, 2012 at 11:54am
so does firewall anything to do even if server and client both are running on the same machine? one and the same comp? what has the firewall to do then? and second: do you mean windows firewalls? I can swear that they are off both for LAN and public internet. crazy
and thank you, your tips are really helpful
Last edited on Mar 23, 2012 at 11:58am
Mar 23, 2012 at 1:22pm
so does firewall anything to do even if server and client both are running on the same machine?
As your client is connecting to 192.168.1.5, it's going thru the firewalled interface. If you want to go thru the loopback adapter, you need to use 127.0.0.1.

I can swear that they are off both for LAN and public internet. crazy
You're not going out to the internet as 192.168.1.5 and 192.168.1.2 are on the same subnet (your local LAN). So the router firewall settings should not be changed. It's the firewall settings on the server machine that need to be set. When you run the server the first time, the firewall should prompt you about accepting connections for the app. It talks about the app, but it really is setting up port 12345.

At the start you said you were using telnet to test the server. What machine did you run it from, the client or the server machine? You need to run it from the client machine in order to confirm the server app can accept connections from the client machine.
Last edited on Mar 23, 2012 at 1:25pm
Mar 23, 2012 at 2:22pm
kbw,
I think you don't understand.
at the beginning I have obviously tested the server and client running on THE SAME MACHINE - so what firewall issue?
I run server on 192.168.1.2 12345 and then on 192.168.1.2 I run client who want to connect with 192.168.1.2 on the port 12345, error 10061 is raised,
why? even only one letter from the whole word should has been sent
Last edited on Mar 23, 2012 at 2:23pm
Mar 23, 2012 at 6:41pm
All in all I have changed settings in windows firewall on windows 7. I have opened 12346 and tried to connect on the same machine. Now I get error 10060.
Mar 25, 2012 at 4:05pm
You don't need to open the firewall if you're running the client and server on the same computer.
Mar 26, 2012 at 9:26am
exactly. so what now? secondly I wonder why now I started to get 10060 error. and still can connect via telnet. must be wrong sth with code becouse netcat can connect even from other computer in my LAN. it is old code, maybe windows sockets now will not work this way.
Mar 26, 2012 at 8:03pm
It must be the client. While running on the same machine, double check the server address is correct. If it doesn't work, try a loopback address, 127.0.0.1.
Last edited on Mar 26, 2012 at 8:03pm
Topic archived. No new replies allowed.