Linux套接字编程

套接字编程:网络通讯编程

		ip地址:

功能:在网络唯一标识一台主机
本质:IPv4: uin32_t
在网路中的数据都必须带有源IP地址和目的IP地址

		PORT端口:

功能:在主机上标识一个进程–表示一个数据应该由那个进程处理
本质:uint16_t 0~65535
在网络中的数据都必须带有源端口和目的端口
特性:一个段口只能被一个进程占用,一个进程可以使用多个端口

        五元组:

源IP地址,目的IP地址,源端口,目的端口,协议

		网络字节序:

字节序:cpu在内存中对数据进行存储的顺序
字节序种类:大端/小端
主机字节序是大端还是小端是由cpu架构决定的:x86架构的cpu都是小端字节序
如何辨别主机字节序:联合体union{int a = 1;uchar b;}
网络字节序的由来:通讯中的两端主机会因为主机字节序的不同而导致出现数据二义性
因此网络通讯字节序标准: 大端字节序 —网络字节序
字节序所针对的类型: int16_t int_32_t int64_t float double

		传输层协议种类以及特性:

TCP(传输控制协议):面向连接,可靠传输,面向字节流
UDP(用户数据报协议):无连接,不可靠,面向数据报
TCP相较于UDP传输性能低,但可以保证可靠传输

		UDP通讯流程:

客户端: 1.创建套接字->2.为套接字绑定地址(客户端不推荐主动绑定)->3.发送数据->4.接收数据->5.关闭套接字

		服务端: 
  1. 创建套接字->2.为套接字绑定地址->3.接收数据->4.发送数据->5.关闭套接字

    int fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    bind(fd,struct sockaddr*, len) srtuct sockaddr_in{sin_family;sin_port,ain_addr.s_addr}
    while(1){
    data_size = recvfrom(fd,buf,buflen,0,&cliaddrl,&addrlen)
    ret = sendto(fd,data,datalen,0&peeraddr,addlen)
    }
    close(fd);
    Linux套接字编程_第1张图片

       TCP通讯流程:

客户端:1.创建套接字->2.绑定地址(不推荐主动绑定)->3.向服务端发起连接->4.发送数据->5.接收数据->6.关闭套接字
服务端:1.创建套接字->2.绑定地址->3.开始监听->获取以完成连接socket接收数据->6.通过获取的已完成连接socket发送数据->7.关闭套接字
int fd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
bind(fd,(struct sockaddr*)&srv_addr,addrlen);
llisten(fd,backlog)—客户端连接请求到来之后在内核中创建套接字,并完成三次握手过程
while()
{
int newfd = accept(fd,(structsockaddr*)&cli_addr,socklen_t *addrlen);
int ret = recv(newfd,buf,buflen,0);
ret<0:表示接收数据出错 ret = 0:表示连接已断开 ret>0: 实际收到的数据长度
int ret = send(newfd,data,datalen,0);
}
close(fd);
connect(fd,&srv_addr,socklen_t addrlen)
Linux套接字编程_第2张图片

    tcp服务端缺陷:

tcp服务端为每个客户端都新建了套接字进行独立通信,但是服务端无法获知那个客户端数据会先到达,因此可能会阻塞在等待连接请求或者等待接收某个客户端数据

     解决方案:

多进程/多线程任务处理
每个线程/进程独立负责一个功能
一个县城/进程复制客户端已完成连接获取功能
为每个客户端都新建一个线程/进程处理独立通信

netstat工具,重点是如何查看各种服务,详见下面博客
https://www.cnblogs.com/ftl1012/p/netstat.html

你可能感兴趣的:(linux,成长之路,坚持)