1

我要编写一个 TCP 服务器(Socket - Linux - C)。我有三个问题:

1)要知道网络(或连接)是否关闭,我是否使用了该选项SO_KEEPALIVE

例如:

int optval = 1;
socklen_t optlen = sizeof(optval); 

if (setsockopt(file_descriptor,SOL_SOCKET,SO_KEEPALIVE,&optval,optlen)<0) {    
Close(file_descriptor);
Print_error("setsockopt() failed");

2)我希望我的服务器联系其他服务器。我的服务器如何知道远程服务器是否关闭?

3)我想写一个并发服务器,所以我用fork()它来创建孩子:

3.1) 我必须处理对共享变量的并发访问,即使它们仅用于读取目的?

3.2)我的进程列表中不会有僵尸......这段代码可以吗?

void sigchld_h (int signum);

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

void sigchld_h (int signum){
    pid_t pid;
    int status;
    while ( (pid = waitpid(-1,&status,WNOHANG)) > 0)
        printf("(%s) INFO - child %d terminated with exit status %d", nome_programma, pid, status);
}

非常感谢您的咨询。

4

2 回答 2

3

要知道网络(或连接)是否关闭,我是否使用了 SO_KEEPALIVE 选项?

你可以这样做。或者,您可以在 TCP/IP 之上实现自己的“心跳”机制。

我希望我的服务器联系其他服务器。我的服务器如何知道远程服务器是否关闭?

服务器无法连接到另一台服务器。连接的人是客户。接受的是服务器。无论如何,您必须使用心跳机制并处理错误以确定服务器何时关闭(意外)。

我想写一个并发服务器,所以我使用 fork() 来创建子

在几乎所有情况下,这都是最糟糕的想法。最好的方法是使用线程数相当少的异步 I/O 。

我必须处理对共享变量的并发访问,即使它们仅用于读取目的?

如果使用fork(),每个进程都会收到自己的内存副本,其中包括变量,因此不需要同步。在线程的情况下,访问只读内存时不需要锁定。

我的进程列表中不会有僵尸......这段代码是否正确?

不,您不能printf()从信号处理程序中调用。只允许异步/重入安全功能。

于 2013-06-14T13:17:30.960 回答
1
  1. SO_KEEPALIVE helps you determine that given TCP connection is dead, meaning the other side had no activity for given time (usually 2 hours). It also helps maintain idle TCP connections through intermediate routers that might just time out connection state due to inactivity. See, for example, here for lengthier explanation.

    Much more useful and convenient way of knowing state of your connected peer is building periodic heartbeat exchange into your application-level protocol.

  2. In this case your server acts as a client. Connect to the remote end and exchange data. You will know the other side is down if you a) cannot connect, or b) receive zero bytes (graceful closing of the socket by the peer), or c) get an error from send(2) saying the pipe is broken. Again, remote server crash is the trickiest to detect. SO_KEEPALIVE would eventually tell you there's a problem, but application heartbeats will tell you much sooner.

  3. fork(2) is the heaviest of the concurrency tools available on modern Unix. Designs based on child process per client connection (and even thread per connection) quickly lead to resource problems, and are generally slow. Explore thread pools and non-blocking sockets along with polling mechanisms like select(2), poll(2), and epoll(7).

于 2013-06-14T13:25:59.463 回答