Tcp socket

Pages: 12
Hi there, i'm in a situation with a server-client issue, the connection is made packets are sent/received but if server restarts then the client must be also restarted in order to allow comunication again.. i don't know exactly where could be the problem
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
void server(string ip) {

	#ifdef WIN32
    WSADATA wsaData;
    if ((WSAStartup(MAKEWORD(2,2), &wsaData)!=0)) {
        cout << SRV_WSA_ERR;
        return;
    }
	#endif

    SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if(sock<0) {
        cout << SRV_SOCK_ERR;
        return;
    } else cout << SRV_SOCK_OK;

    sockaddr_in server_addr, client_addr;


    server_addr.sin_family=AF_INET;
    server_addr.sin_addr.s_addr = inet_addr(ip.c_str());
    server_addr.sin_port=htons(40000);

    socklen_t client_addr_size = sizeof(client_addr);

    struct timeval tv;
    tv.tv_sec = 5;
    setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval));

    if(bind (sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
        cout << SRV_BIND_ERR;
        return;
    } else cout << SRV_BIND_OK;

    int sb;

    if(listen(sock,0)<0) cout << SRV_LISTEN_ERR;
    else cout << SRV_LISTEN_OK;

    SOCKET a = accept(sock, (struct sockaddr *)&client_addr, &client_addr_size);
    if(a<0) cout << SRV_ACCEPT_ERR;
    else cout << SRV_ACCEPT_OK << " " << inet_ntoa(client_addr.sin_addr) << ":" << ntohs(client_addr.sin_port) << "\n";

    while(b_server) {

        sb = recv(a, buffmsg, MTUSIZE, 0);
        if(sb>0) {

            boost::mutex::scoped_lock lock(io_mutex);

            cout << "Received:\n" << buffmsg << "\n";
        }

         Wait(1);
    }
    boost::mutex::scoped_lock lock(io_mutex);
    #ifdef __linux__
        close(sock); close(a);
    #else
        closesocket(a); closesocket(sock);
        WSACleanup();
    #endif

}


int main(int argc, char* argv[]) {


    int s;

    ip=string(argv[1]);
    boost::thread wt_server = boost::thread(boost::bind(server,ip));

    	#ifdef WIN32
    WSADATA wsaData;
    if ((WSAStartup(MAKEWORD(2,2), &wsaData)!=0)) {
        cout << CL_WSA_ERR;
        return 0;
    }
	#endif

    SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if(sock<0) {
        cout << CL_SOCK_ERR;
        return 0;
    } else cout << CL_SOCK_OK;

    sockaddr_in client_addr;

    Wait(100);
    ip=string(argv[2]);

    client_addr.sin_family=AF_INET;
    client_addr.sin_addr.s_addr = inet_addr(ip.c_str());
    client_addr.sin_port=htons(40000);

    struct timeval tv;
    tv.tv_sec = 5;
    setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval));

	
    if(connect(sock, (struct sockaddr *)&client_addr, sizeof(client_addr))<0)
   	cout << CL_CONNECT_ERR;
    else cout << CL_CONNECT_OK;

    while(b_client) {

        cin.getline(getCmd,1000);

        if(strcmp(getCmd,"exit")==0) {
            b_server = b_client = false;
            wt_server.join();
			#ifdef __linux__
			close(sock);
			#else
            closesocket(sock); WSACleanup();
			#endif
        }
        else if(strlen(getCmd)>0) {

            s = send(sock, getCmd, strlen(getCmd)+1, 0);
            if(s<0) cout << CL_SEND_ERR;

        }

        Wait(1);
    }

    return 0;
}

This is what i had done so far, i'm missing something?
Last edited on
i'm in a situation with a server-client issue, the connection is made packets are sent/received but if server restarts then the client must be also restarted in order to allow comunication again
You need to seperate where the application consumes the data from where it get's it from. This decoupling will allow the application layer to request data and the network layer to deal with reconnections transparently.

The server needs to set the REUSE option so that it can re-bind immediately.

The client needs to check for failure, close the connection, then try to reconnect and continue the read into the buffer.
I think you want the client(s) to automatically restart whenever the server is restarted. This shouldn't be a problem. Ensure you are using the appropriate "include" statements.

Check the "while" statements (for both server and client).

There are different methods of writing a server-client program.

It all depends on how you want the client(s) to communicate with the server. You might have to separate/comment the code into server and client.

However, this is an not a complete code. What errors are you getting?
Well if the server is restarted then the connected client is sending messages 'nowhere' and an error is occurred at the 'send' function, i did a every time connection like for every message the client opens a new connection then closing it but this isn't a reliable way.. a reconnect feature would be nice but i don't know exactly the steps for this feature.
client is sending messages 'nowhere'
With TCP, this is impossible. You will know if the send failed.

As I said earlier, you need to re-establish the connection.

Re-establish with only the 'connect()' function or i'll need a new socket for the client? If 'send()' is not ok then i'll have to close the current socket and establish a new one?
You need to close the socket that you're reading from and use connect() to establish a new connection to the new server instance. The server seens the request come in on accept(), so it needs to start know how to continue too.
Hm ok thanks i'll try this out.
Now i have found another problem, if the server is down and the client try to connect then the "connect()" function is causing the client program to exit.. why is this happening?
You need to wait/retry until the server is up, right?
Oh yes you're right, a loop resolved this, now another issue if the server stops while the client is connected then the 'send()' function from client continuously returns the number of characters sent although the server is down.. how can i check if server is up? I mean the 'send' doesn't suppose to return -1 on error? As the manual says
 
On success, these calls return the number of characters sent. On error, -1 is returned, and errno is set appropriately.

Last edited on
send() ought to fail if it cannot send. If send() says it sent something, you should treat it as such.
Well this is weird because although the server is down send() is still sending.. to where i don't know but it never return -1 and in this way i can't see when my server is on or off..
The scenario - server is up, client can connect/send messages everything is ok but if the server goes down then the send() function still return the number of chars sended instead of -1 and yes the server is down for really.
Last edited on
Ups, seems that the problem was from local connection pc - linux virtual machine, on a real environment the send() returns -1 as it should.. such a release!
As a recomandation, my client program send messages every x minutes where x<10 and sometimes instantly at random intervals what do you recomend in this situation keep the connection up or connect and disconnect after the job is done?
You may as well establish a new connection on demand. You'll reduce the load on the server. And you don't seem to actually need a long term connection for sending the odd message here and there.
Alright, thank you, also may i setup a non-blocking socket timeout? It is worth it?
Non-blocking sockets won't help you here. You just need to pay close attention to return codes to determine when you've lost the server and drop into recovery mode.
Hmm i made some memory tests and initially from 600kb memory consumption of client program after 20k connects/disconnects the memory increased at 10mb.. this is not ok, the client it's a function with no memory leaks and no heap declarations everything is supposed to destroy after function completes, what could be the problem?
I can't say without seeing the code.
Pages: 12