简体   繁体   中英

TCP socket receives from wrong port

I have problem with a TCP socket receiving messages with wrong destination port.

The OS is Ubuntu Linux 10.10 and kernel version is 2.6.31-11-rt, but this happens with other kernels, too. The C/C++ program with this problem does this:

  1. A TCP server socket is listening to connections in INADDR_ANY at port 9000.

  2. Messages are received with recv(2) by a TCP message receiver thread. Connection is not closed after reading message, but the thread continues to read from the same connection forever.

  3. Error: also messages to other ports than 9000 are received by the TCP message receiver. For example, when a remote SFTP client connects to the PC where TCP message receiver is listening, it causes the TCP message receiver to receive also the SFTP messages. How is this EVER possible? How can the TCP ports "leak" this way? I think SFTP should use port 22, right? Then how it's possible those messages are visible in port 9000?

More info:

  • At the same time there's a raw socket listening on another network interface, and the interface is in promiscuous mode. Could this have an effect?

  • The TCP connection is not closed in between message receptions. The message listener just keeps reading data from the socket. Is this really a correct way to implement a TCP message receiver?

Has anyone seen this kind of problem? Thanks in advance.

EDIT:

Ok, here is some code. The code looks to be allright, so the main strange thing is, how a TCP socket can ever receive data sent to another port?

/// 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);
}

The TCP connection is not closed in between message receptions. The message listener just keeps reading data from the socket. Is this really a correct way to implement a TCP message receiver?

Yes but it must close the socket and exit when it receives the EOS indication (recv() returns zero).

I think it's ten to one your raw socket and TCP socket FDs are getting mixed up somewhere.

Umm... It appears that it was the raw socket after all which has received the messages. Can see from the log that it's the raw message handler printing out message reception things, not the TCP message handler. Duh...! :S Sorry. So it seems the binding of the raw socket into the other network interface doesn't work correctly. Need to fix that. Funny though that sometimes it works with SSH/SFTP, sometimes it does not.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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