我遇到了一个问题,TCP套接字接收消息时目标端口错误。
操作系统为Ubuntu Linux 10.10,内核版本为2.6.31-11-rt,但在其他内核中也会出现此问题。出现问题的C/C++程序执行以下步骤:
1. TCP服务器套接字正在INADDR_ANY上的9000端口侦听连接。 2. 通过TCP消息接收线程使用recv(2)接收消息。读取消息后不关闭连接,线程将继续从同一连接读取。 3. 错误:TCP消息接收器还会接收到其他端口而不是9000端口的消息。例如,当远程SFTP客户端连接到运行TCP消息接收器的PC时,它会导致TCP消息接收器也接收到SFTP消息。这怎么可能?TCP端口如何“泄漏”?我认为SFTP应该使用22号端口,对吗?那么,这些消息如何在9000端口中可见?
更多信息:
- 同时有一个原始套接字在另一个网络接口上侦听,并且接口处于混杂模式。这会产生影响吗? - TCP连接在消息接收之间未关闭。消息监听器只需从套接字读取数据即可。这真的是实现TCP消息接收器的正确方法吗?
有人遇到过这种问题吗?提前感谢。
编辑:
好的,这里有一些代码。代码看起来没问题,所以主要奇怪的事情是TCP套接字如何接收发送到另一个端口的数据?
操作系统为Ubuntu Linux 10.10,内核版本为2.6.31-11-rt,但在其他内核中也会出现此问题。出现问题的C/C++程序执行以下步骤:
1. TCP服务器套接字正在INADDR_ANY上的9000端口侦听连接。 2. 通过TCP消息接收线程使用recv(2)接收消息。读取消息后不关闭连接,线程将继续从同一连接读取。 3. 错误:TCP消息接收器还会接收到其他端口而不是9000端口的消息。例如,当远程SFTP客户端连接到运行TCP消息接收器的PC时,它会导致TCP消息接收器也接收到SFTP消息。这怎么可能?TCP端口如何“泄漏”?我认为SFTP应该使用22号端口,对吗?那么,这些消息如何在9000端口中可见?
更多信息:
- 同时有一个原始套接字在另一个网络接口上侦听,并且接口处于混杂模式。这会产生影响吗? - TCP连接在消息接收之间未关闭。消息监听器只需从套接字读取数据即可。这真的是实现TCP消息接收器的正确方法吗?
有人遇到过这种问题吗?提前感谢。
编辑:
好的,这里有一些代码。代码看起来没问题,所以主要奇怪的事情是TCP套接字如何接收发送到另一个端口的数据?
/// Create TCP socket and make it listen to defined port
TcpSocket::listen() {
m_listenFd = socket(AF_INET, SOCK_STREAM, 0)
...
bzero(&m_servaddr, sizeof(sockaddr_in));
m_servaddr.sin_family = AF_INET;
m_servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
m_servaddr.sin_port = htons(9000);
bind(m_listenFd, (struct sockaddr *)&m_servaddr, sizeof(sockaddr_in);
...
listen(m_listenFd, 1024);
...
m_connectFd = accept(m_listenFd, NULL, NULL);
}
/// Receive message from TCP socket.
TcpSocket::receiveMessage() {
Uint16 receivedBytes = 0;
// get the common fixed-size message header (this is an own message structure)
Uint16 numBytes = recv(m_connectFd, msgPtr + receivedBytes, sizeof(SCommonTcpMSGHeader), MSG_WAITALL);
...
receivedBytes = numBytes;
expectedMsgLength = commonMsgHeader->m_msgLength; // commonMsgHeader is mapped to received header bytes
...
// ok to get message body
numBytes = recv(m_connectFd, msgPtr + receivedBytes, expectedMsgLength - receivedBytes, MSG_WAITALL);
}
socket()
、bind()
、listen()
、accept()
。你的代码在做什么?能否发布相关部分? - FrankH.bind
控制本地端口。远程端口号只能在调用getpeername()
之后查询,但不能根据远程端口号拒绝连接。 - FrankH.ret = send(m_connectFd, msgPtr, msgLength, 0)
。 - HJK25