C Socket网络编程细节问题
accept
accept()的函数原型如下:
int accept(int socket, struct sockaddr *restrict address,
           socklen_t *restrict address_len);需要注意的是第三个参数address_len,在Linux manual中是这么描述的:
Either a null pointer, if address is a null pointer, or a pointer to a socklen_t object which on input specifies the length of the supplied sockaddr structure, and on output specifies the length of the stored address.
也就是说在调用前后存储的内容是不同的,有各自的作用,在调用之前就需要设置为第二个参数address的大小。
一个正确的accpet应该使用以下的形式:
struct sockaddr_in client_address;
socklen_t client_address_size = sizeof(client_address);
connection_fd = accept(socket_fd, (struct sockaddr *) &client_address, &client_address_size);通信边界
对于一个echo服务,要通过传递数据大小来约定对方下一次read的数据量。一个正确的回显程序的client应当如下:
int len = (int) strnlen(message, BUFFER_SIZE) + 1;
write(connection_fd, &len, sizeof(int));
write(connection_fd, message, len);
read(connection_fd, &len, sizeof(len));
read(connection_fd, message, len);
printf("[echo_rep] %s\n", message);通常来讲对于文本都是通过strnlen来计算长度,但是需要+1以包含最后的\0,否则程序运行之后,很有可能会出现因为\0缺失而把buffer中后面的字符一起打印出来的情况,因为C中不遇到\0,printf()是不会停下来的(卡其脱离太)。
但在read的时候,一定要保证直接按给的数量读取。总之要理解好这一个通信规则。
SIGPIPE
SIGPIPE这一个信号在编写网络应用的时候一定要注意,不对这一个信号量进行处理会导致服务程序的崩溃。
在Linux下使用kill命令模拟程序收到SIGPIPE信号。
kill -PIPE <PID>
pkill --signal=SIGPIPE <Programme Name>Last updated
Was this helpful?