问题描述
在工作中,我的任务是将TCP服务器实现为Modbus从设备的一部分.在堆栈交换和一般的Internet上,我都读了很多书(包括出色的 http://beej.us/guide/bgnet/),但我在设计问题上苦苦挣扎.总而言之,我的设备只能接受2个连接,并且在每个连接上都是传入的Modbus请求,我必须在主控制器循环中对其进行处理,然后以成功或失败状态进行回复.关于如何实现这一点,我有以下想法.
-
具有一个侦听器线程,该线程创建,绑定,侦听和接受连接,然后生成一个新的pthread来侦听连接中的传入数据,并在空闲超时时间后关闭连接.如果当前活动线程数为2,则立即关闭新连接以确保仅允许2个线程.
-
请勿从侦听器线程中产生新线程,而应使用select()来检测传入连接请求以及活动连接上的传入Modbus连接(类似于Beejs指南中的方法).
- 创建2个侦听器线程,每个线程创建一个套接字(相同的IP和端口号),该套接字可以阻止accept()调用,然后关闭套接字fd并处理连接.我在这里(也许是天真的)假设这最多只能允许2个连接,而我可以使用阻塞读取来处理这些连接.
我已经使用C ++很久了,但是对于Linux开发我还是很陌生.如果上述哪种方法最好(如果有的话),以及我对Linux的经验不足意味着它们中的任何一种都不是我真正的坏主意,我将非常欢迎提出任何建议.我渴望避免fork()并坚持使用pthreads,因为传入的modbus请求将被排队并定期读取主控制器循环.预先感谢您的任何建议.
第三个方案不行,只能绑定本地地址一次.
除非您需要进行大量处理,否则我可能会使用第二种选择.
我正在考虑的两个第一个选择的组合是让主线程(程序启动时始终拥有一个主线程)创建两个工作线程,然后进行阻塞的 accept
调用等待新的连接.当新的连接到达时,告诉其中一个线程开始在新的连接上工作,然后回到 accept
上进行阻止.当第二个连接被接受时,您告诉另一个线程在该连接上工作.如果两个连接都已经打开,则要么直到一个连接被关闭,要么等待新连接,然后立即关闭它们.
At work I have been tasked with implementing a TCP server as part of a Modbus slave device. I have done a lot of reading both here on stack exchange and on the internet in general (including the excellent http://beej.us/guide/bgnet/) but I am struggling with a design issue. In summary, my device can accept just 2 connections and on each connection will be incoming modbus requests which I must process in my main controller loop and then reply with success or failure status. I have the following ideas of how to implement this.
Have a listener thread that creates, binds, listens and accepts connections, then spawns a new pthread to listen on the connection for incoming data and close connection after an idle timeout period. If the number of active threads is currently 2, new connections are instantly closed to ensure only 2 are allowed.
Do not spawn new threads from the listener thread, instead use select() to detect incoming connection requests as well as incoming modbus connects on active connections (similar to the approach in Beejs guide).
- Create 2 listener threads each of which creates a socket (same IP and port number) which can block on accept() calls, then close the socket fd and deal with the connection. Here I am (perhaps naively) assuming that this will only allow max of 2 connections which I can deal with using blocking reads.
I have been using C++ for a long time but I am fairly new to Linux development. I would really welcome any suggestions as to which of the above approaches is best (if any) and if my inexperience with Linux means that any of them are really really bad ideas. I am keen to avoid fork() and stick to pthreads as incoming modbus requests are going to be queued and read off a main controller loop periodically. Thanks in advance for any advice.
The third alternative won't work, you can only bind to the local address once.
I would probably use your second alternative, unless you need to do a lot of processing in which case a combination of the first to alternatives might be useful.
The combination of the two first alternative I'm thinking of is to have the main thread (the one you always have when a program starts) create two worker threads, then go a blocking accept
call to wait for a new connection. When a new connection arrives, tell one of the threads to start working on the new connection and go back to block on accept
. When the second connection is accepted you tell the other thread to work on that connection. If both connections are open already, either don't accept until one connection is closed, or wait for new connections but close them immediately.
这篇关于在Linux上编写多线程TCP服务器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!