【socket编程简述】TCP UDP 通信总结、TCP连接的三次握手、TCP断开的四次挥手

Socket:Socket被称做 套接字,是网络通信中的一种约定。
Socket编程的应用无处不在,我们平时用的QQ、微信、浏览器等程序.都与Socket编程有关。

                               三次握手                                                                    四次断开

【socket编程简述】TCP UDP 通信总结、TCP连接的三次握手、TCP断开的四次挥手_第1张图片

面试可能会问:

为什么建立连接只需要三次数据交互,而断开连接需要四次呢?

建立连接时,服务端在监听状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。而关闭连接时,当收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,己方也未必全部数据都发送给对方了,所以己方可以立即close,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送。

UDP协议:用户数据报协议。是一种无连接的传输层协议,提供面向事务的简单不可靠传送服务,
可以保证通讯效率,传输延时小。

socket编程的API接口:

1.(1)创建套接字socket:socket()函数
int socket(int af,int type,int protocol);

//af:地址族   type数据传输方式:

面向连接(SOCK_STREAM)即TCP     

无连接(SOCK_DGRAM)即UDP 

//创建TCP套接字
int tcp_socket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
//创建UDP套接字
int udp_socket = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);

(2)绑定套接字:bind()函数
int bind(int sock,struct sockaddr *addr,socklen_t addrlen);
/*
    sock为socket文件描述符;addr为sockaddr结构体变量的指针;
    addrlen为addr变量的大小,可由sizeof()计算得出
*/
//使用示例:
//将创建的套接字 ServerSock与本地IP 127.0.0.1  端口1413进行绑定

/*创建服务端socket*/
int ServerSock = socket(PF_INET,SOCK_STREAM,IPPORTO_TCP);

/*设置服务端信息*/
struct sockaddr_in ServerSockAddr;
memset(&ServerSockAddr,0,sizeof(ServerSockAddr));             //给结构体ServerSockAddr 清零
ServerSockAddr.sin_family = PF_INET;                                      //使用IPV4地址
ServerSockAddr.sin_addr.s_addr = inet_addr("127.0.0.1");        //本机ip地址
ServerSockAddr.sin_port = htons(1413);                                    //端口号

/*绑定套接字*/
bind(ServerSock,(SOCKADDR*)&ServerSockAddr,sizeof(SOCKADDR));

/*
其中 struct sockaddr_in 类型的结构体变量 用于保存IPv4的IP信息。
若是IPv6,则有对应的结构体,如:
*/
struct sockaddr_in6{
    sa_family_t sin6_family; //地址类型,取值为AF_INET6
    in_port_t sin6_port;       //16位端口号    
    uint32_t sin6_flowinfo;  //IPV6流信息
    uint32_t sin6_scope_id;  //接口范围id
};

(3)建立连接:connect()函数
函数原型:
int connect(int sock,struct sockaddr *serv_addr,socklen_t addrlen);
示例:
int ClientSock = socket(AF_INET,SOCK_STREAM,IPPORTO_TCP);
connect(ClientSock,(SOCKADDR*)&ServerSockAddr,sizeof(SOCKADDR));

(4)监听:listen()函数
函数原型:
int listen(int sock,int backlog);
//sock为需要进入监听状态的套接字;backlog为请求队列的最大长度
示例:/*进入监听状态*/
listen(ServerSock,10);

(5)接收请求:accepet()函数
函数原型:
int accpet(int sock,struct sockaddr *addr,socklen_t *addrlen);
/*
sock 为服务器端套接字。
addr 为 sockaddr_in 结构体变量。
addrlen 为参数 addr 的长度,可由 sizeof() 求得。
*/
示例:/*监听客户端请求,accept函数返回一个新的套接字,发送和接收都是用这个套接字*/
int ClientSock = accept(ServerSock,(SOCKADDR*)&ClientAddr,&len);

(6)关闭:close()函数
函数原型:
int close(int fd);//fd 要关闭的文件描述符
示例:
Close(ServerSock);

(7)数据的接收和发送

数据收发函数有几组:

read()/write()

recv()/send()

readv()/writev()

recvmsg()/sendmsg()

recvfrom()/sendto()

函数原型:

ssize_t read(int fd,void *buf,size_t count);

ssize_t write(int fd,const void *buf,size_t count);

ssize_t send(int sockfd,const void *buf,size_t len,int flags);

ssize_t recv(int sockfd,void *buf,size_t len,int flags);

ssize_t sendto(int sockfd,const void *buf, size_t len,int flags,const struct sockaddr *dest_addr,socklen_taddrlen);

ssize_t recvfrom(int sockfd, void *buf,
 
size_t len,int flags,struct sockaddr *src_addr,socklen_t *addrlen);

ssize_t sendmsg(int sockfd,const struct msghdr *msg,int flags);

ssize_t recvmsg(int sockfd,struct msghdr *msg,int flags);

@资料来源 嵌入式大杂烩

你可能感兴趣的:(Linux,tcp/ip,udp,网络协议)