socket编程笔记

  1. 客户端中如果需要从标准输入中获取数据并‘send’又想同时能够‘recv’的问题
    最好使用select,因为select性能在数量级小的时候性能适合,代码量少,同时监控标准输入和socket。

  2. send函数的注意事项
    不能往标准输入输出发送。只能由recv和read从套字节接收。

  3. select函数做轮询时的注意事项
    返回有事件发生的数量nready,为提高效率,一般多定义一个数组,直接记录已连接的客户端,而不需要遍历文件描述符(0至maxfd),遍历客户端数组时,注意要用BUF_MAX,而不是nready。

  4. 服务器A‘’send‘’,客户端B‘’recv‘’,出现A‘’send‘’一次,B一直‘’recv‘’上次send的内容的异常
    可以从TCP/IP的状态分析出,客户端B已断开,一直处于TIME_WAIT状态,recv等待服务器发送FIN信号,而服务器端并没有发送FIN,造成一直recv。
    造成这个原因源于代码的疏忽,应该在recv中改进(无论客户端还是服务器端均要做处理):如果返回值为0,表示另一方已断开,及时关闭对应的文件描述符(即发送FIN给对方),四次握手才能使双方正常断开。

  5. 心跳机制的应用一般最好在应用层,因为灵活性较好,并且自定义加密。不用改变socket的选项
    一般在子线程下完成,并且当套接字关闭时,应及时在父进程调用pthread_cancel结束掉心跳线程
    服务器子线程:睡眠指定时间周期性轮询所有客户端的心跳时间,将未及时的客户端清除
    客户端子线程:自定义一个数据包,在指定周期发送给服务器。

  6. 代码不应该一开始就考虑效率问题,先从代码整洁实现功能,在优化代码

  7. 多线程下不适合用GDB调试工具进行跟踪,应该灵活使用printf("%s\n",FUNCTION);

  8. 字符串赋值给数组问题
    一般不能直接赋值即:char array[64]; array = “hello linux”; 会出现错误,
    因为array等于&array[0], 他是一个指向int型的地址,无法赋值。
    可以调用函数strcmp\strncmp\memcpy\sprintf进行拷贝。
    sprintf直观,但生成汇编指令较多
    strncmp安全,避免越界导致崩溃,尽量不用strcmp
    memcpy拷贝空间大小,不以 ‘\0’ 作为结束拷贝

  9. 获取时间问题 man time查看
    time_t t;
    int tm = time(&t); // 以秒来表示
    char *tm = ctime(&t); // Sat Oct 12 10:20:12 2019形式
    struct tm *tm = gmtime(&t); // 将时间分为时、分、秒形式存入结构体,例:tm.sec为秒

  10. EPOLL非阻塞下的‘’recv‘’数据防丢失
    recv,通过判断errno是否为中断,是则继续读,不管是<0还是>0都进行判断。不用while循环读。

  11. 客户端调用gets等函数赋值数组时,容易给黑客攻击,出错导致整个系统崩溃,比如接收到的数据大小超出了指定范围,所有从外部输入的数据必须用fgets,strncpy等安全API。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值