以下是 Linux 网络通信核心函数的详细参数说明及示例代码,涵盖 TCP/UDP 的关键接口:
**1. socket()
- 创建套接字
函数原型
int socket ( int domain, int type, int protocol) ;
参数说明
参数 说明 domain
协议族:AF_INET
(IPv4)、AF_INET6
(IPv6)、AF_UNIX
(本地通信) type
套接字类型:SOCK_STREAM
(TCP)、SOCK_DGRAM
(UDP) protocol
通常填 0
,由系统自动选择(如 TCP 或 UDP)
示例
int tcp_sock = socket ( AF_INET, SOCK_STREAM, 0 ) ;
if ( tcp_sock == - 1 ) { perror ( "socket" ) ; exit ( EXIT_FAILURE) ;
}
int udp_sock = socket ( AF_INET, SOCK_DGRAM, 0 ) ;
**2. bind()
- 绑定地址
函数原型
int bind ( int sockfd, const struct sockaddr * addr, socklen_t addrlen) ;
参数说明
参数 说明 sockfd
套接字描述符 addr
指向 sockaddr_in
结构体的指针(存储 IP 和端口信息) addrlen
地址结构体的长度(sizeof(struct sockaddr_in)
)
示例
struct sockaddr_in addr;
memset ( & addr, 0 , sizeof ( addr) ) ;
addr. sin_family = AF_INET;
addr. sin_port = htons ( 8080 ) ;
addr. sin_addr. s_addr = htonl ( INADDR_ANY) ; if ( bind ( sockfd, ( struct sockaddr * ) & addr, sizeof ( addr) ) == - 1 ) { perror ( "bind" ) ; close ( sockfd) ; exit ( EXIT_FAILURE) ;
}
**3. listen()
- 监听连接(TCP)
函数原型
int listen ( int sockfd, int backlog) ;
参数说明
参数 说明 sockfd
已绑定的套接字描述符 backlog
等待连接队列的最大长度(通常设为 5~10)
示例
if ( listen ( sockfd, 5 ) == - 1 ) { perror ( "listen" ) ; close ( sockfd) ; exit ( EXIT_FAILURE) ;
}
**4. accept()
- 接受连接(TCP)
函数原型
int accept ( int sockfd, struct sockaddr * addr, socklen_t * addrlen) ;
参数说明
参数 说明 sockfd
处于监听状态的套接字描述符 addr
用于保存客户端地址信息的结构体指针(可为 NULL
) addrlen
地址结构体的长度指针(可为 NULL
)
示例
struct sockaddr_in client_addr;
socklen_t client_len = sizeof ( client_addr) ;
int client_fd = accept ( sockfd, ( struct sockaddr * ) & client_addr, & client_len) ;
if ( client_fd == - 1 ) { perror ( "accept" ) ; close ( sockfd) ; exit ( EXIT_FAILURE) ;
} printf ( "Client connected from %s:%d\n" , inet_ntoa ( client_addr. sin_addr) , ntohs ( client_addr. sin_port) ) ;
**5. connect()
- 连接服务器(TCP/UDP)
函数原型
int connect ( int sockfd, const struct sockaddr * addr, socklen_t addrlen) ;
示例(TCP)
struct sockaddr_in server_addr;
memset ( & server_addr, 0 , sizeof ( server_addr) ) ;
server_addr. sin_family = AF_INET;
server_addr. sin_port = htons ( 8080 ) ;
server_addr. sin_addr. s_addr = inet_addr ( "192.168.1.100" ) ; if ( connect ( sockfd, ( struct sockaddr * ) & server_addr, sizeof ( server_addr) ) == - 1 ) { perror ( "connect" ) ; close ( sockfd) ; exit ( EXIT_FAILURE) ;
}
**6. send()
/ recv()
- 发送/接收数据(TCP)
函数原型
ssize_t send ( int sockfd, const void * buf, size_t len, int flags) ;
ssize_t recv ( int sockfd, void * buf, size_t len, int flags) ;
参数说明
参数 说明 sockfd
已连接的套接字描述符 buf
数据缓冲区指针 len
数据长度 flags
控制标志(通常填 0
)
示例
char * msg = "Hello, Server!" ;
if ( send ( client_fd, msg, strlen ( msg) , 0 ) == - 1 ) { perror ( "send" ) ;
}
char buffer[ 1024 ] ;
ssize_t n = recv ( client_fd, buffer, sizeof ( buffer) , 0 ) ;
if ( n == - 1 ) { perror ( "recv" ) ;
} else if ( n == 0 ) { printf ( "Connection closed\n" ) ;
} else { buffer[ n] = '\0' ; printf ( "Received: %s\n" , buffer) ;
}
**7. sendto()
/ recvfrom()
- 发送/接收数据(UDP)
函数原型
ssize_t sendto ( int sockfd, const void * buf, size_t len, int flags, const struct sockaddr * dest_addr, socklen_t addrlen) ; ssize_t recvfrom ( int sockfd, void * buf, size_t len, int flags, struct sockaddr * src_addr, socklen_t * addrlen) ;
示例
struct sockaddr_in dest_addr;
dest_addr. sin_family = AF_INET;
dest_addr. sin_port = htons ( 8080 ) ;
dest_addr. sin_addr. s_addr = inet_addr ( "192.168.1.100" ) ; sendto ( udp_sock, "Hello" , 5 , 0 , ( struct sockaddr * ) & dest_addr, sizeof ( dest_addr) ) ;
struct sockaddr_in src_addr;
socklen_t src_len = sizeof ( src_addr) ;
char buffer[ 1024 ] ;
recvfrom ( udp_sock, buffer, sizeof ( buffer) , 0 , ( struct sockaddr * ) & src_addr, & src_len) ;
**8. close()
- 关闭套接字
函数原型
int close ( int sockfd) ;
示例
close ( client_fd) ;
close ( server_fd) ;
**9. setsockopt()
- 设置套接字选项
函数原型
int setsockopt ( int sockfd, int level, int optname, const void * optval, socklen_t optlen) ;
示例(设置地址重用)
int reuse = 1 ;
if ( setsockopt ( sockfd, SOL_SOCKET, SO_REUSEADDR, & reuse, sizeof ( reuse) ) == - 1 ) { perror ( "setsockopt" ) ;
}
完整 TCP 服务端示例
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <unistd.h>
# include <arpa/inet.h> int main ( ) { int server_fd = socket ( AF_INET, SOCK_STREAM, 0 ) ; if ( server_fd == - 1 ) { perror ( "socket" ) ; exit ( EXIT_FAILURE) ; } int reuse = 1 ; setsockopt ( server_fd, SOL_SOCKET, SO_REUSEADDR, & reuse, sizeof ( reuse) ) ; struct sockaddr_in addr; memset ( & addr, 0 , sizeof ( addr) ) ; addr. sin_family = AF_INET; addr. sin_port = htons ( 8080 ) ; addr. sin_addr. s_addr = htonl ( INADDR_ANY) ; if ( bind ( server_fd, ( struct sockaddr * ) & addr, sizeof ( addr) ) == - 1 ) { perror ( "bind" ) ; close ( server_fd) ; exit ( EXIT_FAILURE) ; } if ( listen ( server_fd, 5 ) == - 1 ) { perror ( "listen" ) ; close ( server_fd) ; exit ( EXIT_FAILURE) ; } printf ( "Server listening on port 8080...\n" ) ; while ( 1 ) { struct sockaddr_in client_addr; socklen_t client_len = sizeof ( client_addr) ; int client_fd = accept ( server_fd, ( struct sockaddr * ) & client_addr, & client_len) ; if ( client_fd == - 1 ) { perror ( "accept" ) ; continue ; } char * response = "HTTP/1.1 200 OK\r\nContent-Length: 12\r\n\r\nHello World!" ; send ( client_fd, response, strlen ( response) , 0 ) ; close ( client_fd) ; } close ( server_fd) ; return 0 ;
}
总结
函数协作流程 : TCP 服务端 :socket()
→ bind()
→ listen()
→ accept()
→ send()/recv()
→ close()
TCP 客户端 :socket()
→ connect()
→ send()/recv()
→ close()
UDP 通信 :socket()
→ bind()
(可选) → sendto()/recvfrom()
→ close()
关键细节 : 字节序转换 :使用 htons()
, ntohs()
等函数处理端口和 IP 地址。错误处理 :所有函数调用后需检查返回值。资源释放 :通信结束后必须调用 close()
关闭套接字。