#include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <signal.h> #include <unistd.h> #include <stdlib.h> #include <assert.h> #include <stdio.h> #include <string.h> static bool stop = false; static void handle_term( int sig ) { stop = true; } int main( int argc, char* argv[] ) { signal( SIGTERM, handle_term ); if( argc <= 3 ) { printf( "usage: %s ip_address port_number backlog\n", basename( argv[0] ) ); return 1; } const char* ip = argv[1]; int port = atoi( argv[2] ); int backlog = atoi( argv[3] ); // 1.创建socket // int domanin: 协议族: PF_UNIX: UNIX本地域协议族 PF_INET: TCP/IPv4协议族 PF_INET6: TCP/IPv6协议族 // int type: SOCK_STREAM(流服务):TCP SOCK_UGRAM(数据报):UDP int sock = socket( PF_INET, SOCK_STREAM, 0 ); assert( sock >= 0 ); // 2.确定socket地址 struct sockaddr_in address; bzero( &address, sizeof( address ) ); // 地址族:AF_UNIX: UNIX本地域协议族 AF_INET: TCP/IPv4协议族 AF_INET6: TCP/IPv6协议族 address.sin_family = AF_INET; inet_pton( AF_INET, ip, &address.sin_addr ); // 转换为网络字节序:大段 address.sin_port = htons( port ); // 3.命名socket int ret = bind( sock, ( struct sockaddr* )&address, sizeof( address ) ); assert( ret != -1 ); // 4.监听socket ret = listen( sock, backlog ); assert( ret != -1 ); while ( ! stop ) { sleep( 1 ); } close( sock ); return 0; }
执行
./5-3testlisten 10.120.225.64 12345 5 # 监听12345 backlog使用5 telnet 10.120.225.64 12345 & netstat -nt | grep 12345
结果
netstat -nt | grep 12345 tcp 0 0 10.120.225.64:12345 10.143.44.169:63208 SYN_RECV tcp 0 0 10.120.225.64:12345 10.120.225.64:52750 SYN_RECV tcp 0 0 10.120.225.64:52750 10.120.225.64:12345 ESTABLISHED tcp 0 0 10.120.225.64:12345 10.120.225.64:52746 ESTABLISHED tcp 0 0 10.120.225.64:52746 10.120.225.64:12345 ESTABLISHED tcp 0 0 10.120.225.64:52748 10.120.225.64:12345 ESTABLISHED tcp 0 0 10.120.225.64:52745 10.120.225.64:12345 ESTABLISHED tcp 0 0 10.120.225.64:12345 10.120.225.64:52745 ESTABLISHED