繁体   English   中英

三个问题,以创建一个TCP服务器 - 套接字,Linux与C

[英]Three questions in order to create a TCP server - socket, Linux with C

我要写一个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);
}

非常感谢您的咨询。

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

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

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

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

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

这几乎是每种情况下最糟糕的想法。 执行此操作的最佳方法是使用具有相当少的线程数的异步I / O.

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

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

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

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

  1. SO_KEEPALIVE可帮助您确定给定的TCP连接已死,这意味着另一方在给定时间内(通常为2小时)没有活动。 它还有助于通过中间路由器维护空闲的TCP连接,这些中间路由器可能由于不活动而暂停连接状态。 例如,请参阅此处以获得更长的解释。

    了解连接对等体状态的更有用和方便的方法是在应用程序级协议中构建定期心跳交换。

  2. 在这种情况下,您的服务器充当客户端。 连接到远程端并交换数据。 如果你a)无法连接,或者b)接收零字节(对等端正常关闭套接字),或者c)从send(2)收到管道坏了的错误,你就会知道另一边是关闭的。 同样,远程服务器崩溃是最难检测的。 SO_KEEPALIVE最终会告诉你有问题,但应用心跳会告诉你更快。

  3. fork(2)是现代Unix上最重的并发工具。 基于每个客户端连接的子进程(甚至每个连接的线程)的设计很快导致资源问题,并且通常很慢。 探索线程池非阻塞套接字以及select(2)poll(2)epoll(7)等轮询机制。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM