简体   繁体   English

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

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

I'm going to write a TCP server (Socket - Linux - C). 我要写一个TCP服务器(Socket - Linux - C)。 I have three questions: 我有三个问题:

1) For know if the network (or connectivity) is down, have I use the option SO_KEEPALIVE ? 1)要知道网络(或连接)是否已关闭,我是否使用SO_KEEPALIVE选项?

For instance: 例如:

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) I want that my server contacts other server. 2)我希望我的服务器联系其他服务器。 How my server know if the remote server shutdown? 我的服务器如何知道远程服务器是否关闭?

3) I want write an concurrent server and so I use fork() in order to create child: 3)我想写一个并发服务器,所以我使用fork()来创建子:

3.1) I have to handle concurrent access to shared variables even if they are only for read purpose? 3.1)我必须处理共享变量的并发访问,即使它们仅用于读取目的?

3.2) I won't have zombie in my process list...Can this code be right? 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);
}

Thank you very much for the consulting. 非常感谢您的咨询。

For know if the network (or connectivity) is down, have I use the option SO_KEEPALIVE? 要知道网络(或连接)是否已关闭,我是否使用SO_KEEPALIVE选项?

You can do that. 你可以做到这一点。 Alternatively, you may implement your own “heartbeat” mechanism on top of TCP/IP. 或者,您可以在TCP / IP之上实现自己的“心跳”机制。

I want that my server contacts other server. 我希望我的服务器联系其他服务器。 How my server know if the remote server shutdown? 我的服务器如何知道远程服务器是否关闭?

A server cannot connect to another server. 服务器无法连接到其他服务器。 The one who connects is a client. 连接的人是客户。 The one who accepts is a server. 接受的是服务器。 At any rate, you have to use a heartbeat mechanism and handle errors to determine when server goes down (unexpectedly). 无论如何,您必须使用心跳机制并处理错误以确定服务器何时停机(意外)。

I want write an concurrent server and so I use fork() in order to create child 我想写一个并发服务器,所以我使用fork()来创建子

This is the worst idea ever in nearly every case. 这几乎是每种情况下最糟糕的想法。 The best way to do this is to use asynchronous I/O with considerably low number of threads. 执行此操作的最佳方法是使用具有相当少的线程数的异步I / O.

I have to handle concurrent access to shared variables even if they are only for read purpose? 我必须处理共享变量的并发访问,即使它们仅用于读取目的?

If you use fork() , each process receives its own copy of memory, which includes variables, so no synchronization is necessary. 如果使用fork() ,每个进程都会收到自己的内存副本,其中包含变量,因此不需要同步。 In case of threads, you do not need to lock when accessing read-only memory. 在线程的情况下,访问只读内存时不需要锁定。

I won't have zombie in my process list...Can this code be right? 我的进程列表中不会有僵尸......这段代码可以正确吗?

No, you are not allowed to call printf() from a signal handler. 不,您不能从信号处理程序调用printf() Only async/reentrance safe functions are permitted. 仅允许异步/重入安全功能。

  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). SO_KEEPALIVE可帮助您确定给定的TCP连接已死,这意味着另一方在给定时间内(通常为2小时)没有活动。 It also helps maintain idle TCP connections through intermediate routers that might just time out connection state due to inactivity. 它还有助于通过中间路由器维护空闲的TCP连接,这些中间路由器可能由于不活动而暂停连接状态。 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. 如果你a)无法连接,或者b)接收零字节(对等端正常关闭套接字),或者c)从send(2)收到管道坏了的错误,你就会知道另一边是关闭的。 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. SO_KEEPALIVE最终会告诉你有问题,但应用心跳会告诉你更快。

  3. fork(2) is the heaviest of the concurrency tools available on modern Unix. fork(2)是现代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) . 探索线程池非阻塞套接字以及select(2)poll(2)epoll(7)等轮询机制。

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

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