您的当前位置:首页正文

Linux UDP编程流程

来源:九壹网

UDP编程流程

UDP 提供的是无连接、不可靠的、数据报服务。服务器端和客户端没有什么本质上的区别。编程流程如下:

服务器端代码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.创建套接字
    int sockfd=socket(AF_INET,SOCK_DGRAM,0);
    if(sockfd==-1)
    {
        printf("创建失败");
        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.接收客户端的消息,谁发来数据就接收谁的数据,并没有和任何客户端建立连接
        recvfrom(sockfd,buff,127,0,(struct sockaddr*)&caddr,&len);
        //客户端的信息(ip和端口)存放到caddr,caddr指定数据的来源,中记录着是谁发的数据
        printf("buff(%d)=%s\n",ntohs(caddr.sin_port),buff);
    //4.向客户端回复数据
        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.创建套接字
    int sockfd=socket(AF_INET,SOCK_DGRAM,0);
    if(sockfd==-1)
    {
        printf("创建失败");
        exit(1);
    }

    struct sockaddr_in saddr;//服务器的地址,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("输入数据:");
        fgets(buff,128,stdin);

        if(strncmp(buff,"end",3)==0)
        {
            break;
        }

        //2.向服务器端发送数据
        sendto(sockfd,buff,sizeof(buff),0,(struct sockaddr*)&saddr,sizeof(saddr));

        memset(buff,0,sizeof(buff));

        //3.接收服务器端回复的数据
        recvfrom(sockfd,buff,127,0,(struct sockaddr*)&saddr,&len);

        printf("buff=%s\n",buff);
    }

    //4.关闭套接字
    close(sockfd);

}

运行结果:

从结果可以看出,当服务器端启动之后,可以同时启动多个客户端与客户端通信,但是两个客户端的端口号是不同的。

UDP协议无连接的特点

将服务器端关闭再重启后,客户端依旧可以与服务器端通信,如下图所示:

如果服务器端关闭后,客户端向服务器端发送数据就会发生阻塞,阻塞在客户端的recvfrom这个地方,因为服务器没启动,端口没有人使用,那么数据就会被丢掉,所以没有服务器端给客户端回复数据,所以就会阻塞在recvfrom这个地方。如下图:

此时客户端代码cli.c执行完了sendto,接下来执行recvfrom的时候就被阻塞住了,因为没有服务器端给客户端回复消息,此时发送的aaaaaa发给本主机的6000端口,但是本主机的6000端口没有被占用,也就是6000端口没有被使用,所以所发送的数据aaaaaa就直接被丢掉了,所以也不会有服务器端给客户端回复消息,客户端就会在recvfrom这个地方阻塞住。

UDP协议数据报的特点

将服务器端代码ser.c中的recvfrom那一行的代码修改为如下情况,让服务器端一次只收一个字符:

recvfrom(sockfd,buff,1,0,(struct sockaddr*)&caddr,&len);

此时的运行结果:

因篇幅问题不能全部显示,请点此查看更多更全内容

Top