socket初接触---多用户服务器简单交互(上)

socket是什么?它处于应用层和传输层之间的一个抽象层(就是你想象出来的它处于这两者之间),叫套接字(本质上是tcp/ip抽象出的一些方法可以通过它来调用,而我们在应用层可以使用它来进行通信),实现了一个接口的功能。
传输层广为使用的tcp/ip协议栈处于内核之中,我们对socket进行编程,就是主动编写(网络)进程间的通信(靠的是tcp/ip协议),实现一些真正通信上的服务功能。
在学习socket之前,我们首先应该先了解一下它的数据结构

//通用地址套接字结构
struct  sockaddr{
        uint8_t  sin_len;       //整个sockaddr的长度

        sa_family_t  sin_family;//地址家族,使用的协议

        char  sa_data[14];      //由sin_family决定它的形式
}

另外,在网络传输中还需要注意字节序的传输规定:
字节序是什么概念?
简单来说就是字节在内存中存储的格式,在大部分机器上分成两种:大端字节序和小端字节序。
大端:最高有效位存储在最低内存地址处,最低有效位存储在最高内存地址处。
小端:最高有效位存储于最高内存地址处,最低有效位存储于最低内存地址处。
大体看下面这张图片就知道了:
16进制的0x12345678的不同字节序排列

很好理解,从2^7,2^6 ….. 2^0,前面的是低地址,但对内存而言却是高内存。
在网络中,我们统一了使用大端字节序。
说了这么多,终于到了下面我们最经常用的几个字节序转换函数:

//这里是主机字节序 --> 网络字节序,在传输数据时候使用
uint32_t  htonl(uint32_t  hostlong);

uint16_t  htons(uint16_t  hostshort);

//这里是网络字节序 --> 主机字节序,在数据到本地重新编码的时候使用
uint32_t  ntohl(uint32_t  netlong);

uint16_t  ntohs(uint16_t  netshort);

其中s—short两个字节,l—long四个字节,h—host,n—network
另外还有常用的一些地址转换函数:

int  inet_aton(const  char* cp,struct  in_addr* inp);

in_addr_t  inet_addr(const  char* cp);

char* inet_ntoa(struct  in_addr_in);

为什么要转换地址函数?
一般我们所熟悉的地址一般是32位ip地址,但是在网络传输中,机器不会认识这种格式的地址。所以,我们需要将它转换成为网络传输中所识别的地址,一般是一个10位的整形数字。
在上面的三种函数中,一般客户端要绑定本机某个地址的时候使用第二种方法。
在实际使用中我们继续讨论。

接下来我们再引入一个概念——字节流
由于TCP是基于字节流的传输数据,所以它的发送端不限定发送的数据的大小,因为接收端可以不限次数地去接收,同时它是端对端的,什么校验,去重,按序号整合啥的都有,因为TCP是非常稳定的,这唯一的不足之处就是相对UDP效率低。

知道了字节流,那就说下套接字的几种类型(也就是所谓的协议家族)
1.流式套接字(stream):面向连接的,可靠的数据传输服务,数据无差错,无重复的发送,而且按发送顺序接受

2.数据报套接字(dgram):无连接服务。可能丢失,重复,混乱

3.原始套接字(raw):允许对低层(IP层)的协议直接访问,它可以自行组装数据包(伪装本地IP,本地MAC),可以接受本机网卡上的数据帧。

另外还得再提一下一个数据结构,就是servaddr的内部结构,这里举一个ipv4的sockarrd_in(它的socket结构,其他的socket结构都类似,就是在通用socket上感觉地址家族决定了不同的data数据结构)

struct  sockaddr_in{
        uint8_t  sin_len;
        //实际中ipv4的协议家族是AF_INET
        sa_family_t  sin_family;
        //上面的两个是通用socket都有的基本元素

        in_port_t  sin_port;
        //网络(in ternet)地址,4个字节
        struct  in_addr  sin_addr;
        //保留字段,其中的8是sockaddr总字节大小减去结构体中所有其他成员所占字节得到的数字
        unsigned  char  sin_zero[8];
}

好了,大概了解上面所提到的所有知识点之后,下一章开始写代码。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值