当前位置:首页 » 《资源分享》 » 正文

【操作系统】Linux之网络编程(UDP)(头歌作业)

15 人参与  2024年12月22日 08:01  分类 : 《资源分享》  评论

点击全文阅读


第1关:UDP套接字创建与端口绑定

#include <sys/types.h>#include <sys/socket.h>#include <arpa/inet.h>#include <stdio.h>#include <errno.h>#include <string.h>/************************ * port: 需要绑定的端口号 * 返回值: 调用成功返回0,否则返回-1*************************/int UDPSocket(unsigned short port){int ret = -1;/********** BEGIN **********/int sockfd;    struct sockaddr_in server_addr;    // 创建UDP套接字    sockfd = socket(AF_INET, SOCK_DGRAM, 0);    if (sockfd == -1)    {        printf("创建UDP套接字失败: %s\n", strerror(errno));        return -1;    }    // 初始化服务器地址结构体    memset(&server_addr, 0, sizeof(server_addr));    server_addr.sin_family = AF_INET;    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);    server_addr.sin_port = htons(port);    // 绑定端口    ret = bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));    if (ret == -1)    {        printf("绑定端口失败: %s\n", strerror(errno));        close(sockfd);        return -1;    }    ret = 0;/********** END **********/return ret;}

第2关:UDP数据传送

#include <sys/types.h>#include <sys/socket.h>#include <arpa/inet.h>#include <stdio.h>#include <errno.h>#include <string.h>#include <unistd.h>#define PORT 8888int main(){int sockfd;sockfd = socket(AF_INET, SOCK_DGRAM, 0);if(sockfd == -1){return -1;}struct sockaddr_in addr;bzero(&addr, sizeof(addr));    //清空addr.sin_family = AF_INET;addr.sin_port = htons(PORT);addr.sin_addr.s_addr = htonl(INADDR_ANY);//与PORT端口进行绑定if(bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) == -1){return -1;}char data[100];//接收客户端传来的数据,并打印出来(提示:换行打印)//同时将接收到的数据原样发送给客户端//当接收到"exit"字符串时,退出当前程序,不打印出"exit"字符串//提示:在每次接收字符串前要将存放字符串的变量清空/********** BEGIN **********/struct sockaddr_in clientAddr;    socklen_t clientAddrLen = sizeof(clientAddr);    while (1)    {        // 每次接收前清空存放字符串的变量        memset(data, 0, sizeof(data));        ssize_t recvLen = recvfrom(sockfd, data, sizeof(data), 0, (struct sockaddr *)&clientAddr, &clientAddrLen);        if (recvLen == -1)        {            printf("接收数据失败: %s\n", strerror(errno));            continue;        }        else if (recvLen > 0)        {            // 去掉字符串末尾可能的换行符等空白字符            while (data[recvLen - 1] == '\n' || data[recvLen - 1] == '\r' || data[recvLen - 1] == '\t' || data[recvLen - 1] == ' ')            {                data[recvLen - 1] = '\0';                recvLen--;            }            if (strcmp(data, "exit") == 0)            {                break;            }            // 换行打印接收到的数据            printf("%s\n", data);            // 将接收到的数据原样发送给客户端            ssize_t sendLen = sendto(sockfd, data, recvLen, 0, (struct sockaddr *)&clientAddr, clientAddrLen);            if (sendLen == -1)            {                printf("发送数据失败: %s\n", strerror(errno));            }        }    }/********** END **********/close(sockfd);return 0;}

第3关:项目实战

#include <stdio.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <string.h>#include <errno.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>//定义数据块大小char data[16];//定义服务器端口和服务器地址#define PORT 8889#define SERVER_IP "127.0.0.1"int main(int argc, char *argv[]){int sockfd;sockfd = socket(AF_INET, SOCK_DGRAM, 0);if(sockfd == -1){return -1;}struct sockaddr_in servAddr;int servAddrLen = sizeof(servAddr);bzero(&servAddr, sizeof(servAddr));servAddr.sin_family = AF_INET;servAddr.sin_port = htons(PORT);servAddr.sin_addr.s_addr = inet_addr(SERVER_IP);//由用户传入的要下载文件的名称char *downLoadFileName = argv[1];printf("%s\n", argv[1]);//先在本地创建要下载的文件int fd = fd = open(downLoadFileName, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);//向服务器发送要上传文件的名称sendto(sockfd, downLoadFileName, strlen(downLoadFileName), 0, (struct sockaddr *)&servAddr, servAddrLen);     /********** BEGIN **********/char ack[16];    int recvLen;    // 循环接收服务器发送的数据块    while (1)    {        // 接收服务器发送的数据块        recvLen = recvfrom(sockfd, data, sizeof(data), 0, (struct sockaddr *)&servAddr, &servAddrLen);        if (recvLen == -1)        {            printf("接收数据失败: %s\n", strerror(errno));            continue;        }        // 根据数据块类型判断是否下载完成        if (data[0] == 'e')        {            // 下载完成,关闭文件并退出程序            close(fd);            break;        }        else if (data[0] == 'c')        {            // 数据块为文件内容,将内容写入本地文件            write(fd, &(data[1]), recvLen - 1);        }        // 向服务器发送接收确认请求        sendto(sockfd, "OK", strlen("OK"), 0, (struct sockaddr *)&servAddr, servAddrLen);        // 清空数据块数据部分(除了类型标识字节)        memset(&(data[1]), 0, sizeof(data) - 1);    }/********** END **********/close(sockfd);return 0;}

点击全文阅读


本文链接:http://m.zhangshiyu.com/post/204970.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1