学科分类
目录
Linux编程

C/S模型-UDP

在创建socket时,若将socket()函数中的参数type设置为SOCK_DGRAM,程序将采用UDP传输协议,以数据包的形式传输数据。

案例2:编写C/S模式的程序,分别创建服务器和客户端。客户端的功能是从终端获取一个字符串发送给服务器,然后接收服务器返回的字符串并打印;服务器的功能是从客户端发来的字符,将每个字符转换为大写再返回给客户端。案例实现如下。

udpserver.c //服务器端

 1    #include <string.h>
 2    #include <netinet/in.h>
 3    #include <stdio.h>
 4    #include <unistd.h>
 5    #include <strings.h>
 6    #include <arpa/inet.h>
 7    #include <ctype.h>
 8    #define MAXLINE 80                            //最大连接数
 9    #define SERV_PORT 6666                        //服务器端口号
 10    int main(void)
 11    {
 12        struct sockaddr_in servaddr, cliaddr;    //定义服务器与客户端地址结构体
 13        socklen_t cliaddr_len;                    //客户端地址长度
 14        int sockfd;                                //服务器socket文件描述符
 15        char buf[MAXLINE];
 16        char str[INET_ADDRSTRLEN];
 17        int i, n;
 18        sockfd = socket(AF_INET, SOCK_DGRAM, 0);//创建服务器端套接字文件
 19         //初始化服务器端口地址
 20        bzero(&servaddr, sizeof(servaddr));    //地址结构体清零
 21        servaddr.sin_family = AF_INET;            //指定协议族
 22        servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
 23        servaddr.sin_port = htons(SERV_PORT);    //指定端口号
 24         //绑定服务器端口地址
 25        bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
 26        printf("Accepting connections ...\n");
 27         //数据传输
 28        while (1) {
 29            cliaddr_len = sizeof(cliaddr);
 30             //接收数据
 31            n=recvfrom(sockfd,buf,MAXLINE,0,(struct sockaddr*)&cliaddr,
 32                          &cliaddr_len);
 33            if (n == -1)
 34                perror("recvfrom error");
 35            printf("received from %s at PORT %d\n", 
 36                    inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)),
 37                    ntohs(cliaddr.sin_port));
 38             //服务器端操作,小写转大写
 39            for (i = 0; i < n; i++)
 40                buf[i] = toupper(buf[i]);
 41            n =sendto(sockfd, buf,n,0,(struct sockaddr *)&cliaddr, 
 42                         sizeof(cliaddr));
 43            if (n == -1)
 44                perror("sendto error");
 45        }
 46        close(sockfd);
 47        return 0;
 48    }

udpclient.c //客户端

 1    #include <stdio.h>
 2    #include <string.h>
 3    #include <unistd.h>
 4    #include <netinet/in.h>
 5    #include <arpa/inet.h>
 6    #include <strings.h>
 7    #include <ctype.h>
 8    #define MAXLINE 80
 9    #define SERV_PORT 6666
 10    int main(int argc, char *argv[])
 11    {
 12        struct sockaddr_in servaddr;
 13        int sockfd, n;
 14        char buf[MAXLINE];
 15        sockfd = socket(AF_INET, SOCK_DGRAM, 0);
 16        bzero(&servaddr, sizeof(servaddr));
 17        servaddr.sin_family = AF_INET;
 18        inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);
 19        servaddr.sin_port = htons(SERV_PORT);
 20         //发送数据到客户端
 21        while (fgets(buf, MAXLINE, stdin) != NULL) {
 22            n =sendto(sockfd, buf, strlen(buf),0,(struct sockaddr *)&servaddr,
 23                         sizeof(servaddr));
 24            if (n == -1)
 25                perror("sendto error");
 26             //接收客户端返回的数据
 27            n = recvfrom(sockfd, buf, MAXLINE, 0, NULL, 0);
 28            if (n == -1)
 29                perror("recvfrom error");
 30             //将接收到的数据打印到终端
 31            send(STDOUT_FILENO, buf, n,0);
 32        }
 33        close(sockfd);
 34        return 0;
 35    }

编译以上两端代码,打开两个终端窗口,先执行服务器端程序,再执行客户端程序,同时输入需要转换的字符串,服务器端和客户端对应的终端中分别打印如下信息:

服务器端:

Accepting connections ...
received from 127.0.0.1 at PORT 33059
received from 127.0.0.1 at PORT 33059

客户机端:

hello
HELLO
world
WORLD

由程序执行结果可知,服务器成功换成客户端发来的字符串转,案例实现成功。

点击此处
隐藏目录