简体   繁体   English

为accept()系统调用工作

[英]Working for accept() system call

I have to write a program which will check how many clients can connect to a single server(socket) in C. 我必须编写一个程序来检查C中有多少个客户端可以连接到单个服务器(套接字)。

I used Beej's guide to programming as a reference, and have realized that after a single client connects to the server, more clients cannot simultaneously send messages to the same server. 我以Beej的编程指南作为参考,并意识到在单个客户端连接到服务器后,更多的客户端无法同时将消息发送到同一服务器。 Only after the first connection is closed will the backlogged message from the second client be delivered. 仅在第一个连接关闭后,才会传递第二个客户端的积压消息。

Since my newness to socket programming, I'm not sure if "accept" is the correct system call to be used. 由于我是套接字编程的新手,所以我不确定“ accept”是否是要使用的正确系统调用。 Also, what should the value of BACKLOG be in listen to make to see the stress the server can handle. 同样,在监听中应该知道BACKLOG的值是什么,以查看服务器可以处理的压力。

Any help? 有什么帮助吗?

accept() is the right system call. accept()是正确的系统调用。 It returns a new file descriptor associated with the new incoming connection, whilst leaving the original socket prepared to receive more connections. 它返回与新传入的连接相关联,同时使准备接收更多的连接原始套接字的文件描述符。

However once you've accepted that incoming connection, it's usual to have the main process either: 但是,一旦您接受了该传入连接,通常需要执行以下主要过程:

  1. create a thread to handle that socket 创建一个线程来处理该套接字
  2. fork a new process which inherits the new file descriptor. 派生一个继承新文件描述符的新进程。
  3. use select() , epoll() , etc to poll for reads on that socket 使用select()epoll()等轮询该套接字上的读取

If you don't do that, any subsequent read() on the accepted connection will block, meaning that you can't call accept() again. 如果不这样做,则接受的连接上的任何后续read()都将阻塞,这意味着您无法再次调用accept()

The backlog parameter to listen() only serves to tell the kernel how many sockets may be allowed to remain in their initial "connecting" state prior - it's not normally necesssary to tune it very much. listen()的backlog参数仅用于告诉内核可以允许多少个套接字在其初始的“连接”状态之前保留-通常不需要非常调优。

Section 7.2 of Beej's guide covers the way to do this that most C programmers learn first. 《 Beej指南》的第7.2节介绍了大多数C程序员首先要学习的方法。 The example at the end of section 7.2 should be exactly what you want. 7.2节末尾的示例应该正是您想要的。

Basically, you use select to let your program wait for either data to be received on one of the connections you have already accepted or for a new client to be trying to connect. 基本上,您可以使用select来让程序等待已接受的连接之一上的数据被接收,或者等待新的客户端尝试连接。 Then you check to see what happened and handle it. 然后检查以了解发生了什么并处理。 (Unfortunately, the example does teach one bad habit -- it forgets to set the sockets to non-blocking mode, so it can deadlock in accept if the connection is no longer pending.) (不幸的是,该示例确实教导了一个坏习惯-它忘记将套接字设置为非阻塞模式,因此如果连接不再挂起,它可能会死锁于accept 。)

The basic idea is this: 基本思想是这样的:

1) Set up basic structures to keep track of clients, initialize them to reflect the fact that you have no clients. 1)设置基本结构以跟踪客户端,初始化它们以反映您没有客户端的事实。

2) Set up a listening socket for new connections. 2)设置用于新连接的监听套接字。

3) Wait for something to happen using select . 3)使用select等待事件发生。 You can wait for a new client to connect, data to be received from an existing client, data to be able to be sent to an existing client, an error to occur on an existing connection, or a certain amount of time to pass. 您可以等待新客户端连接,从现有客户端接收到的数据,可以发送到现有客户端的数据,在现有连接上发生错误或经过一定时间。 Use the structures that track your clients to make sure you wait for data to be received from all your existing clients. 使用跟踪客户的结构来确保您等待所有现有客户的数据接收。

4) Handle whatever happened. 4)处理任何发生的事情。 If a new client tries to connect, accept the connection and update your tracking structures. 如果新客户端尝试连接,请accept连接并更新您的跟踪结构。 If data was received from a client, see if it completes a command and, if so, process it. 如果从客户端接收到数据,请查看它是否完成了命令,如果可以,请对其进行处理。 If one of your clients closed the connection or there was an error on that connection, clean up by closing your socket and updating the tracking. 如果您的一位客户关闭了连接或该连接出现错误,请通过关闭套接字并更新跟踪进行清理。

5) Go back to step 3. 5)返回步骤3。

This is called 'I/O multiplexing'. 这称为“ I / O复用”。 There are other ways to do it, but this is the way most C programmers learn first. 还有其他方法可以做到,但这是大多数C程序员最先学习的方法。

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

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