解析socket编程的相关函数

1.什么是套接字

一个完整的网络通信需要一个五元组来标识:协议、本地地址、本地端口号、远端地址、远端端口号。

TCP用主机的IP地址加上主机上的端口号作为TCP连接的端点,这种端点就叫做套接字

 

流式套接字(SOCK_STREAM):TCP(The Transmission Control Protocol)协议。

流式套接字用于提供面向连接、可靠的数据传输服务。该服务将保证数据能够实现无差错、无重复发送,并按顺序接收

 

数据报套接字(SOCK_DGRAM):UDP(User Datagram Protocol)协议

数据报套接字提供了一种无连接的服务。该服务并不能保证数据传输的可靠性,数据有可能在传输过程中丢失或出现数据重复,且无法保证顺序地接收到数据。进行数据的传输 

 

原始套接字(SOCK_RAW):IP、 ICMP协议

原始套接字(SOCKET_RAW)允许对较低层次的协议直接访问,比如IP、 ICMP协议,它常用于检验新的协议实现,或者访问现有服务中配置的新设备,因为RAW SOCKET可以自如地控制Windows下的多种协议,能够对网络底层的传输机制进行控制,所以可以应用原始套接字来操纵网络层和传输层应用。

比如,我们可以通过RAW SOCKET来接收发向本机的ICMP、IGMP协议包,或者接收TCP/IP栈不能够处理的IP包,也可以用来发送一些自定包头或自定协议的IP包。网络监听技术很大程度上依赖于SOCKET_RAW

 

2.什么是大小端(主机字节序)

一个整型变量一般是32位的,由4个字节组成。这些字节的地址是有高低地址之分

发送主机通常将发送缓冲区中的数据按内存地址从低到⾼的顺序发出;

接收主机把从网络上接到的字节依次保存在接收缓冲区中,也是按内存地址从低到⾼的顺序保存;

 

如果将低8位存放在4个字节中的低地址位,称为小端字节序

如果将低8位存放在4个字节的高地址位,则为大端字节序

网络字节序被规定为大端字节序!!!

 

3.什么是网络字节序,为什么要考虑网络字节序

网络字节顺序是TCP/IP中规定好的一种数据表示格式,它与CPU类型、操作系统等无关,从而可以保证数据在不同主机之间传输时能够被正确解释。

因为一台主机有可能是⼤端机或者是⼩端机, 所以对数据的存储方式是不一样的,为了解决这一差异,TCP/IP规定的网络字节序来发送/接收数据;

如果当前发送主机是⼩端, 就需要先将数据转成⼤端; 否则就忽略, 直接发送即可;

 

4.常见的socket API

// 创建 socket ⽂件描述符 (TCP/UDP, 客户端 + 服务器)

//根据指定的地址族,数据类型和协议来分配一个套接字的描述字及其所用的资源。

//参数:协议族(IPV4)AF_INET    类型(字节流)SOCK_STREAM    指定协议protocol  当参数为0时,会自动选择第二个参数类型对应的默认协议。

//参数:协议族(IPV6)PF_INET    类型(数据报)SOCK_DGRAM     指定协议protocol  当参数为0时,会自动选择第二个参数类型对应的默认协议。

int socket(int domain, int type, int protocol);    

// 绑定端⼝号 (TCP/UDP, 服务器)        

int bind(int socket, const (struct sockaddr *)address,socklen_t address_len);        //返回的fd    addr_in结构体的强转    len

// 开始监听socket (TCP, 服务器)

int listen(int socket, int backlog);

// 接收请求 (TCP, 服务器)

int accept(int socket, struct sockaddr* address,socklen_t* address_len);

// 建⽴连接 (TCP, 客户端)

int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

 

5.如何理解accept返回值

返回的是一个不同的sock_fd,这个socket保存的是你客户端的socket信息,socket编程服务端客户端都需要知道 协议、服务器ip、服务器端口、客户端ip、客户端端口这些信息

成功返回之后,tcp服务器与客户端将使用这个新的sock_fd进行通信,失败返回一个非法值(宏)

6.如何理解listen的第二个参数

三次握手的 过程中会维护着两个队列SYN_RCVD(处于三次握手中的),ESTABLISHED(已经完成三次握手,但还没被服务器accept的)

1:未完成队列:每个这样的SYN分节对应其中一项,已有某个客户端发出并到达服务器,而服务器正在等待完成相应的TCP三路握手过程。这些套接口处于SYN_RCVD

2:已完成队列:每个已经完成TCP三次握手过程的客户对应其中一项。 这些套接口处于ESTABLISHED

第二个参数就是未完成队列的大小

指的是在完成TCP三次握手后的队列。即在系统accept之前的队列。

如果系统没有调用accpet把这个队列的数据拿出来。一旦这个队列满了。未连接队列的请求过不来。导致未连接队列里的请求会超时或者拒绝。如果系统调用了accpet队列接受请求数据。那么就会把接受到请求移除已完成队列。 这时候已完成队列又可以使用了。

最后 说了如果开启了syncookies  忽略listen的第二个参数。

7.bind失败可能的原因

试图绑定一个已经在使用的端口。

试图绑定一个正在处于TIME_WAIT状态的端口。

绑定一个为小于1024的端口号,因为1到1024是保留端口号

bind 最常见的用法是关联端口号和服务器,并使用通配符地址(INADDR_ANY),它允许任何接口为到来的连接所使用。

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值