手把手做网站页面,wordpress获取菜单栏,湖南火电建设有限公司网站,网页设计版式图片一.什么是Socket(套接字#xff09; 定义#xff1a;就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。一个套接字就是网络上进程通信的一端#xff0c;提供了应用层进程利用网络协议交换数据的机制。从所处的地位来讲#xff0c;套接字上联应用进程#x… 一.什么是Socket(套接字 定义就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。一个套接字就是网络上进程通信的一端提供了应用层进程利用网络协议交换数据的机制。从所处的地位来讲套接字上联应用进程下联网络协议栈是应用程序通过网络协议进行通信的接口是应用程序与网络协议栈进行交互的接口。 定义比较难理解总之我们认为通过socket及各层协议我们可以实现网络通信。网络通信的本质就是不同主机上进程的通信那么我们是如何通过socket定位到一个主机的进程的呢答案是ip定位网络上唯一台主机端口号主机上唯一一个进程通过socket绑定ip和端口号我们可以定位网络上唯一一个进程。
二.认识TCP协议和UDP协议
TCP
传输控制协议TCPTransmission Control Protocol是一种面向连接的、可靠的、基于字节流的传输层通信协议由IETF的RFC 793 [1]定义。
TCP旨在适应支持多网络应用的分层协议层次结构。 连接到不同但互连的计算机通信网络的主计算机中的成对进程之间依靠TCP提供可靠的通信服务。TCP假设它可以从较低级别的协议获得简单的可能不可靠的数据报服务。 原则上TCP应该能够在从硬线连接到分组交换或电路交换网络的各种通信系统之上操作。
我们主要理解以下TCP协议四个特点: 传输层协议 有连接 可靠传输 面向字节
UDP
此外UDP协议也是传输层常用的协议,UDP是User Datagram Protocol的简称中文名是用户数据报协议是OSI参考模型中的传输层协议它是一种无连接的传输层协议提供面向事务的简单不可靠信息传送服务。
具有以下四个特定
传输层协议无连接不可靠传输面向数据报
对于UDP本文不主要讲解
三. TCP中socket常用API 的讲解
1.sockaddr 结构
socket API 是一层抽象的网络编程接口,适用于各种底层网络协议,如 IPv4、IPv6,以及后面要讲的 UNIX Domain Socket. 然而, 各种网络协议的地址格式并不相同。简单了解就是由于socket不仅能用于网络通信还能用于本地通信等描述socket的地址格式应该不同。
主要有以下俩种格式 第一种用于网络第二种用于本地通信。
socket的地址在socket的多种API中我们都会用到为了程序的通用性, 可以接收 IPv4, IPv6, 以及 UNIX Domain Socket 各种类型的 sockaddr 结构体指针做为参数 因此我们采用一个 struct sockaddr *类型来接受各种参数就类似于c中的多态。表示如下 我们来了解网络通信需要的struct sockaddr_in的各种字段
struct sockaddr_in {short sin_family; // 2 字节 地址族e.g. AF_INET, AF_INET6unsigned short sin_port; // 2 字节 16位TCP/UDP 端口号 e.g. htons(3490)struct in_addr sin_addr; // 4 字节 32位IP地址char sin_zero[8]; // 8 字节 不使用
}; sin_family主要用来定义是哪种地址族地址族就是一个协议族所使用的地址集合也是用宏来表示不同的地址族这个宏的形式是AF开头比如IP地址族为AF_INET,AF的意思是ADDRESS FAMILYsin_port主要用来保存端口号sin_addr主要用来保存IP地址信息sin_zero没有特殊含义
struct in_addr的内容如下
struct in_addr {unsigned long s_addr; // 32位IPV4地址打印的时候可以调用inet_ntoa()函数将其转换为char *类型.
};
可以看出struct in-addr是用于存储IP的。
这里我们需要注意网络通信中的字节序是大端字节序我们传入的ip和端口号需要从主机序列转换为网络序列。
2.socket函数(创建socket) #include sys/types.h #include sys/socket.hint socket(int domain, int type, int protocol); 1.domain 参数 domain 参数指定套接字的协议族常见的协议族有 AF_INETIPv4、AF_INET6IPv6和 AF_UNIX本地套接字等。前2个用于网络通信最后一个用于本地通信。2.type 参数 type 参数指定套接字的类型常见的类型有 SOCK_STREAM流套接字/TCP 套接字和 SOCK_DGRAM数据报套接字/UDP套接字等。3.protocol 参数protocol 参数指定使用的协议常见的协议有 IPPROTO_TCPTCP 协议和 IPPROTO_UDPUDP 协议等。如果指定为 0则会根据 domain 和 type 参数自动选择协议。 4.返回值socket()打开一个网络通讯端口,如果成功的话,就像 open()一样返回一个文件描述符;
3.bind函数(绑定ip和端口号 #include sys/types.h#include sys/socket.h
int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);bind()函数的作用是将ip和端口号绑定到socket()函数创建的文件的文件描述符上。
在服务端需要我们手动绑定客户端操作系统会自动帮我们绑定
第一个参数sockfd是我们需要绑定的文件描述符。第二个是地址第三个是地址的长度。
bind()成功返回 0,失败返回-1。
4. listen函数(监听连接请求) #include sys/types.h #include sys/socket.hint listen(int sockfd, int backlog);第一个是socket文件描述符.
第二个参数backlog是侦听队列的长度。 在进程正在处理一个连接请求的时候可能还存在其它的连接请求。因为TCP连接是一个过程所以可能存在一种半连接的状态有时由于同时尝试连接的用户过多使得服务器进程无法快速地完成连接请求。如果这个情况出现了服务器进程希望内核如何处理呢内核会在自己的进程空间里维护一个队列以跟踪这些完成的连接但服务器进程还没有接手处理的连接还没有调用accept函数的连接这样的一个队列内核不可能让其任意大所以必须有一个大小的上限。这个backlog告诉内核使用这个数值作为上限。
listen()成功返回 0,失败返回-1
5.accept函数(接受连接函数) #include sys/types.h #include sys/socket.hint accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);第一个参数还是表示文件描述符
第二个参数addr 是一个传出参数,accept()返回时传出客户端的地址和端口号 如果给 addr 参数传 NULL,表示不关心客户端的地址; 第三个参数addrlen 参数是一个传入传出参数(value-result argument), 传入的是调用者提 供的, 缓冲区 addr 的长度以避免缓冲区溢出问题, 传出的是客户端地址结构体的实 际长度(有可能没有占满调用者提供的缓冲区);
返回值是一个新的文件描述符用新的文件描述符来进行信息的传输和接收。我们可以看做拉客的过程第一个文件描述符主要用来门外拉客监听和接受第二个用于店内一对一服务客人信息的传输和接收)
6.connect函数(连接函数客户端使用) #include sys/types.h #include sys/socket.hint connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);客户端需要调用 connect()连接服务器; connect 和 bind 的参数形式一致, 区别在于 bind 的参数是自己的地址, 而 connect 的参数是对方的地址;
connect()成功返回 0,出错返回-1。
7.流程总结
客户端socket()----accetp()操作系统会自动调用bind()。
服务器端socket()----bind()----listen()----asscept()。