UDP 提供的是無連接、不可靠的、數(shù)據(jù)報服務(wù)。服務(wù)器端和客戶端沒有什么本質(zhì)上的區(qū)別。編程流程如下:
服務(wù)器端代碼ser.c如下:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
int main()
{ //1.創(chuàng)建套接字
int sockfd=socket(AF_INET,SOCK_DGRAM,0);
if(sockfd==-1)
{
printf("創(chuàng)建失敗");
exit(1);
}
struct sockaddr_in saddr,caddr;
memset(&saddr,0,sizeof(saddr));
saddr.sin_family=AF_INET;
saddr.sin_port=htons(6000);
saddr.sin_addr.s_addr=inet_addr("127.0.0.1");
//2.指定套接字的地址,綁定ip和端口
int res=bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));
if(res==-1)
{
printf("綁定失敗");
exit(1);
}
int len=sizeof(caddr);
while(1)
{
char buff[128]={0};
//3.接收客戶端的消息,誰發(fā)來數(shù)據(jù)就接收誰的數(shù)據(jù),并沒有和任何客戶端建立連接
recvfrom(sockfd,buff,127,0,(struct sockaddr*)&caddr,&len);
//客戶端的信息(ip和端口)存放到caddr,caddr指定數(shù)據(jù)的來源,中記錄著是誰發(fā)的數(shù)據(jù)
printf("buff(%d)=%s\n",ntohs(caddr.sin_port),buff);
//4.向客戶端回復(fù)數(shù)據(jù)
sendto(sockfd,"ok",2,0,(struct sockaddr*)&caddr,sizeof(caddr));
}
}
客戶端代碼cli.c如下:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
int main()
{
//1.創(chuàng)建套接字
int sockfd=socket(AF_INET,SOCK_DGRAM,0);
if(sockfd==-1)
{
printf("創(chuàng)建失敗");
exit(1);
}
struct sockaddr_in saddr;//服務(wù)器的地址,ip和端口
memset(&saddr,0,sizeof(saddr));
saddr.sin_family=AF_INET;
saddr.sin_port=htons(6000);
saddr.sin_addr.s_addr=inet_addr("127.0.0.1");
int len =sizeof(saddr);
while(1)
{
char buff[128]={0};
printf("輸入數(shù)據(jù):");
fgets(buff,128,stdin);
if(strncmp(buff,"end",3)==0)
{
break;
}
//2.向服務(wù)器端發(fā)送數(shù)據(jù)
sendto(sockfd,buff,sizeof(buff),0,(struct sockaddr*)&saddr,sizeof(saddr));
memset(buff,0,sizeof(buff));
//3.接收服務(wù)器端回復(fù)的數(shù)據(jù)
recvfrom(sockfd,buff,127,0,(struct sockaddr*)&saddr,&len);
printf("buff=%s\n",buff);
}
//4.關(guān)閉套接字
close(sockfd);
}
運行結(jié)果:
從結(jié)果可以看出,當(dāng)服務(wù)器端啟動之后,可以同時啟動多個客戶端與客戶端通信,但是兩個客戶端的端口號是不同的。
將服務(wù)器端關(guān)閉再重啟后,客戶端依舊可以與服務(wù)器端通信,如下圖所示:
如果服務(wù)器端關(guān)閉后,客戶端向服務(wù)器端發(fā)送數(shù)據(jù)就會發(fā)生阻塞,阻塞在客戶端的recvfrom這個地方,因為服務(wù)器沒啟動,端口沒有人使用,那么數(shù)據(jù)就會被丟掉,所以沒有服務(wù)器端給客戶端回復(fù)數(shù)據(jù),所以就會阻塞在recvfrom這個地方。如下圖:
此時客戶端代碼cli.c執(zhí)行完了sendto,接下來執(zhí)行recvfrom的時候就被阻塞住了,因為沒有服務(wù)器端給客戶端回復(fù)消息,此時發(fā)送的aaaaaa發(fā)給本主機的6000端口,但是本主機的6000端口沒有被占用,也就是6000端口沒有被使用,所以所發(fā)送的數(shù)據(jù)aaaaaa就直接被丟掉了,所以也不會有服務(wù)器端給客戶端回復(fù)消息,客戶端就會在recvfrom這個地方阻塞住。
將服務(wù)器端代碼ser.c中的recvfrom那一行的代碼修改為如下情況,讓服務(wù)器端一次只收一個字符:
recvfrom(sockfd,buff,1,0,(struct sockaddr*)&caddr,&len);
此時的運行結(jié)果:
因篇幅問題不能全部顯示,請點此查看更多更全內(nèi)容
Copyright ? 2019- 91gzw.com 版權(quán)所有 湘ICP備2023023988號-2
違法及侵權(quán)請聯(lián)系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市萬商天勤律師事務(wù)所王興未律師提供法律服務(wù)