socket 学习使用笔记

socket 学习使用笔记

socket简单tcp收发

服务端

struct sockaddr_in6 addr;
int fd = socket(AF_INET6, SOCK_STREAM, 0);

memset(&addr, 0, sizeof(addr));
addr.sin6_family = AF_INET6;
addr.sin6_port = htons(serverPort);
addr.sin6_addr = in6addr_any;

bind(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));

// 这之后客户端connect才能成功
listen(fd, 128);

/// 可重复accept
// 这个时候客户端才能收发消息
clientFd = accept4(fd, (struct sockaddr *)&addr, &addLen, 0);

// 可重复消息
recv
send

close(clientFd);

close(fd);

客户端

struct sockaddr_in addr;
int fd = socket(AF_INET, SOCK_STREAM, 0);

addr.sin_family = AF_INET;
addr.sin_port = htons(serverPort);
inet_pton(AF_INET, serverAddress, addr->sin_addr.s_addr);

// 值得注意的是这个connect还没完成全部的握手,只是连上了远端,要等对端accept才可以。实际上可能还不能发送数据的情况。
connect(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));


// 可重复消息
recv
send

close(fd);

特性添加

ipv4/ipv6

普通教程会直言,各个协议一一对应即可,但是实际上更妙的时,ipv4的客户端实际也可以连接到ipv6的服务端种,因为数据传输过去之后,尽管绑定的是v6接口,但端口是共享的,而且这个v4地址也会被转义后能被识别解读。

因此只需要实现监听v6的any并监听端口,即可完成对所有地址的监控服务。无论是v4还是v6。

另外,需要注意scope_id的问题。本地局部链路(地址开头fe80)的通信,在多网卡环境中无法直接通信,因为每个网卡都会初始化一个本地局部链路,他们的路由一样fe80,没办法区分从哪个网卡发出消息导致报错invalid arg。 这个时候可以指定sin6——scope_id = if_nametoindex(“接口名,如eth0”);

timeout

默认情况下无线等待收发数据,这明显不符合实际应用。网络中故障或对端下线时需要及时发现并结束。因此setoption设置超时参数并结束才是正事。

ssl

http使用明文传输数据,这明显不够安全。因此,大伙捉摸着使用一套加密+鉴权操作来增强安全性。

其安全性分成两部分,一个是对对端的鉴权,也即确认对端是目标对象。这个通过ca证书,也即可信第三方来做鉴权。而后通过证书中的公钥和对端进行加密通信,沟通通信因子,并完成连接构建,畅想加密通信。

使用时则可以把soket绑定到ssl对象中,然后再进行消息的收发,即可完成安全的通信。如下所示:

epoll

使用阻塞接口要达到高性能是极其困难的,而非阻塞接口的处理中,又要面临如何同时轮询多个连接的问题。

epoll将任务注册在内核,当事件到来时,告知到事件队列中。用户通过轮询事件队列,即可完成对所有连接的轮询。

难能可贵的是,他的使用也非常简单,唯一比较值得注意的是,如果任务开销比较繁重,记得把建立连接的监听单独epoll,从而避免他们长期无法响应而无法连接。

SO_REUSEPORT

光如此还不够,实际上可能会发现,单个线程对任务的监听,建立连接无法满足需求的情况。这个时候如果使用多个线程去监听的话就需要额外的锁去避免冲突了。

SO_REUSEPORT 则支持这些线程同时监听,并负载均衡地分配连接到这些线程或进程。

但直到2021年,他的既有缺陷仍在讨论中: 进程数变化时可能导致连接reset,无法服务。可能只能适用于多线程模型比较符合这个特征,让他不算是bug。

粘包、半包处理

归根到底是tcp数据传输是流式的,没有数据格式存在,导致一个消息可能分开几次到达(半包), 或者几个消息一次到达(粘包)。这里的到达是指一次recv。

这要求我们去拆包、拼包,进而避免这种问题。一般处理方法有下列3种:

  1. 固定长度
    1. 极致的简单,但较多的额外数据传输开销
  2. 头部(告知长度) + 数据
    1. 定义固定,较好兼容字符
  3. 特殊字符分割
    1. 开销较小,不需要复杂格式
    2. 问题:消息中可能包含该特殊字符,需要转义
  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值