9.26 udp
上节回顾:
tcp特点 面向连接的 可靠的 流式服务
1 三次握手 四次挥手
connect发起连接开始三次握手 close开始挥手
2 应答确认 超时重传 滑动窗口 乱序重排 去重
3 send recv 次数不对应 粘包(两次发送的数据被一次收取)
多线程:
主线程创建多个线程 将c交给各线程 主线程只负责accept()
多进程:
命令:
netstat
查看tcp连接的状态:time_wait状态
发送缓冲区 接收缓冲区当前的字节数
当前进程使用的端口号
本节重点:
udp 无连接 不可靠 数据报
udp服务器 客户端的编程流程:
udp ser udp cli
socket() socket()
bind()
recvfrom() sendto()
sendto() recvfrom()
close() close()
ser:
recvfrom() 谁的都可以接收 (记录发送的客户端的ip,port)
cli:
sendto() 必须知道服务器的ip,port
(udpser.c)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <assert.h>
int main()
{
int sockfd = socket(AF_INET,SOCK_DGRAM,0); //数据报服务的套接字
assert(sockfd != -1);
struct sockaddr_in saddr;
memset(&saddr,0,sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_port = htons(6000); //端口 网络字节序列 大端
saddr.sin_assr.s_addr = inet_addr("127.0.0.1");
int res = bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));
assert(res != -1)
while(1)
{
struct sockaddr_in caddr;
int len = sizeof(caddr);
char buff[128] = {0};
int n = recvfrom(sockfd,buff,127,0,(struct sockaddr*)&caddr,&len);
printf("recv(%d):%s\n",n,buff);
sendto(sockfd,"ok",2,0,(struct sockaddr*)&caddr,sizeof(caddr));
}
}
(udpcli.c)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <assert.h>
int main()
{
int sockfd = socket(AF_INET,SOCK_DGRAM,0); //数据报服务的套接字
assert(sockfd != -1);
struct sockaddr_in saddr; //代表服务端的地址 :ip port
memset(&saddr,0,sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_port = htons(6000); //指定服务器的端口
saddr.sin_assr.s_addr = inet_addr("127.0.0.1"); //指定服务器的ip
while(1)
{
char buff[128] = {0};
printf("input:\n");
fgets(buff,128,stdin);
if(strncmp(buff,"end",3) == 0)
{
break;
}
sendto(sockfd,buff,strlen(buff),0,(struct sockaddr*)&saddr,sizeof(saddr));
memset(buff,0,128);
int len = sizeof(saddr);
recvfrom(sockfd,buff,127,0,(struct sockaddr*)&saddr,&len);
printf("buff=%s\n",buff);
}
close(sockfd);
}
注意:
服务器必须指定端口
客户端无需指定端口
TCP与UDP区别:
TCP建立连接后所有数据发往一个客户端 报文可积攒之后一起发送 可能发生粘包
UDP不能确定每次发送的客户端都一样 一个数据需要一次性输完会发送一个数据报直接发送 不会发生粘包