关于Socket编程你应该知道的

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/MBuger/article/details/74890420

简介

Socket是进程通讯的一种方式,即调用这个网络库的一些API函数实现分布在不同主机的相关进程之间的数据交换。简单来说就是两个进程,跨计算机的通讯,此时就要用到Socket。Socket也可以说是IP地址加上端口号,这样也就可以唯一的标识一个网络上的进程。
端口号:用来辨别本地通讯进程,一个本地的进程在通讯时均会占用一个端口号,不同的进程端口号不同,因此在通讯前必须要分配一个没有被访问的端口号。

为什么要有Socket

Socket的存在是为了简化基于C/S模式(客户端和服务端模式)的网络进程间通讯。C/S模式下的进程间通讯比较复杂,因为一台机器上能运行多个进程,有客户端也有服务端进程。而Socket因为是基于TCP/IP协议栈,它用IP地址加端口号标识一个进程,服务端被动等待客户端的呼叫,然后建立连接,通信。

Socket编程的基本操作函数

首先使用socket函数能够返回一个Socket描述符,把它想象成文件描述符。
接下来客户端使用connect函数连接socket地址,连接成功后socket描述符就可以读写了。
bind函数将文件描述符和socket地址绑定。
listen函数将socket描述符转化成“监听描述符”,供服务器监听客户端的请求用。
accept函数等待客户端的请求,返回“已连接描述符”,后续可以用来与客户端通信(使用底层的I/O函数,read(),write(),send(),recv())。
close函数则是将套接字关闭,并立即返回到调用进程。

socket编程的细节问题

1.socket的API适用于各种网络协议,例如IPv4,IPv6,然而各种网络协议的地址格式并不相同。有一个结构专门用来存放socket地址,sockaddr,如图从左到右分别是IPv4,IPv6和UNIX Domain Socket的地址类型。
socket地址了结构
IPv4和IPv6的地址格式定义在netinet/in.h中,IPv4地址⽤sockaddr_in结构体表⽰,包括16位端⼜号和32位IP地址,IPv6地址⽤sockaddr_in6结构体表⽰,包括16位端⼜号、128位IP地址和⼀些 控制字段。UNIX Domain Socket的地址格式定义在sys/un.h中,⽤sockaddr_un结构体表示。各种socket地址结构体的开头都是相同的,前16位表⽰整个结构体的长度,后16位表⽰地址类型。IPv4、IPv6和UNIX Domain Socket的地 址类型分别定义为常数AF_INET、AF_INET6、AF_UNIX。这样,只要取得某种sockaddr结构体的 ⾸地址,不需要知道具体是哪种类型的sockaddr结构体,就可以根据地址类型字段确定结构体中的 内容。因此,socket API可以接受各种类型的sockaddr结构体指针做参数,例如bind、accept、connect等函数,这些函数的参数应该设计成void 类型以便接受各种类型的指 针,但是sock API的实现早于ANSI C标准化,那时还没有void 类型,因此这些函数的参数都 ⽤struct sockaddr *类型表⽰,在传递参数之前要强制类型转换⼀下。

2.很多机器在存储数据的时候都是按照小端字节序的模式存储,但是在网络传输的时候,数据是按照大端字节序的模式传输,所以我们就需要装换其模式,就会使用下面的几个函数
字节序转换函数
这些函数名很好记,h表⽰host,n表⽰network,l表⽰32位长整数,s表⽰16位短整数。例 如htonl表⽰将32位的长整数从主机字节序转换为⽹络字节序,例如将IP地址转换后准备发送。如果主机是⼩端字节序,这些函数将参数做相应的⼤⼩端转换然后返回,如果主机是⼤端字节序,这些函数不做转换,将参数原封不动地返回。

3.在网络传输的时候为了节省空间,我们会用一个32位无符号整型数据in_addr表示IPv4地址。但是在我们平常我们会采用点分十进制的字符串来表示IP地址。所以在我们传参或者接收到IP地址数据的时候我们需要把它进行一次转换。
字符串转in_addr函数
字符串转IP

in_addr转字符串函数
IP转字符串

猜你喜欢

转载自blog.csdn.net/MBuger/article/details/74890420