简体   繁体   中英

Does this socket bind fail? If so why?

(Why doesn't this code work?)

I'm learning Linux socket programming. The following code is based on an example at this site that I'm learning from:

#include <iostream>
#include <arpa/inet.h>
#include <cstring>
#include <cstdlib>
#include <unistd.h>

int main( int argc, char* argv[] )
{
  // Create a socket with domain AF_INET and type SOCK_STREAM.
  int sd_inet;
  if ( -1 == ( sd_inet = socket( AF_INET, SOCK_STREAM, 0 ) ) )
  {
    std::cout << "socket() failed." << std::endl;
    return 1;
  }

  // Create an AF_INET address.
  struct sockaddr_in si;
  memset( &si, 0, sizeof( si ) );
  si.sin_family = AF_INET;
  si.sin_port = htons( 9000 );
  const unsigned char addr[] = { 127, 0, 0, 23 }; // Local loopback.
  std::memcpy( &si.sin_addr.s_addr, addr, sizeof( addr ) );
  int si_len = sizeof( si );

  // Bind the address to the socket.
  if ( -1 == bind( sd_inet, (struct sockaddr*)&si, si_len ) )
  {
    std::cout << "bind() failed." << std::endl;
    close( sd_inet );
    return 1;
  }

  system( "netstat -pa --tcp 2>/dev/null " );
  close( sd_inet );

  return 0;
}

Desired behavior : The output of this program should display an entry for the bound socket created by this program.

Problem/Question : The output of netstat does not show the expected bound socket. Can someone please help identify what is wrong?

What else I have tried : I was unclear whether the "127.0.0.23" address should generically work, or if that was supposed to be a valid IP address that I have "assigned" to a network card on my box, so I experimented with assigning "127.0.0.1" and htonl( INADDR_ANY ) to si.sin_addr.s_addr , as well as trying a sin_port value of 0 , but none of those experiments yielded different results.

Compiled with gcc 4.8.3.

You need to call either listen() or connect() on the socket to get it into a state that shows up in netstat . After the block that calls bind() , add:

  if (-1 == listen(sd_inet, 5)) {
      std::cout << "listen() failed." <<std::endl;
      close(sd_inet);
      return 1;
  }

and then you'll see it:

tcp        0      0 *:9000                  *:*                     LISTEN      9912/testbind   

To add a why to Barmar's answer, although netstat --help doesn't explain this, the manpage does:

-a, --all
Show both listening and non-listening (for TCP this means established connections) sockets

That is, "all" is a bit of a misnomer.

Your socket is neither listening (because you did not call listen() yet) nor "non-listening" according to the above definition (because you did not connect() anywhere either).

Therefore, it is not listed.

You would see it in lsof output in its embryonic state; quoting Barmar, it'll be something like:

 sock 0,7 0t0 248811876 can't identify protocol 

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