📒
Notes
  • 个人笔记
  • Machine Learning
    • Tensorflow
      • Text
        • Keras构建RNN
        • 字词嵌入
        • 字词嵌入示例程序
      • Data processing
        • tf.data数据加载
      • Tensorflow Tricks
    • 循环神经网络概览
    • Pix2Pix
  • Assembly Language
    • DOS中的Debug模式
    • LOOP指令
    • 8086CPU
    • 标志位寄存器
    • 汇编指令
    • 汇编语言源程序格式
  • Linux System
    • Systemctl 服务脚本
    • Linux端口占用
    • Btrfs文件系统
    • C Socket网络编程细节问题
  • Hexo
    • Hexo下的Tag/Categories栏
    • Git备份博客
    • Hexo博客基本部署
  • Kernel
    • C语言中消息队列实现
    • Linux内核的进程调度函数
    • Linux内核模块的编译
    • Linux Kernel概述
  • Linux Software
    • Linux软件安装与配置
  • Docker
    • OVS+Docker网络构建
    • Docker分层垃圾清理
  • C
    • CMakeList语法
Powered by GitBook
On this page
  • accept
  • 通信边界
  • SIGPIPE

Was this helpful?

  1. Linux System

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>
PreviousBtrfs文件系统NextHexo

Last updated 5 years ago

Was this helpful?