网络编程day3——UDP服务器与客户端搭建流程
创始人
2025-01-20 09:35:32
0次

1.UDP框架

1.1服务器

   

    socket  --- 创建套接字
        SOCK_STREAM  -- 流式套接字     TCP
        SOCK_DGRAM   -- 数据报套接字   UDP

(这个是socket创建套接字的函数参数列表中,type的选项:

        int socket(int domain, int type, int protocol);

  • type:指定套接字的通信类型,例如 SOCK_STREAM(TCP)或 SOCK_DGRAM(UDP))

    
​    bind    --- 绑定本机地址和端口   

​    recvfrom   --- 接收数据并获取数据来自哪里
​    sendto     --- 指定向哪里发送数据

1.2客户端

    socket  --- 创建套接字
        SOCK_STREAM  -- 流式套接字     TCP
        SOCK_DGRAM   -- 数据报套接字   UDP
    
​    bind(可选)    --- 绑定本机地址和端口   
 
​    sendto     --- 指定向哪里发送数据

​    recvfrom   --- 接收数据并获取数据来自哪里

2.接口函数

        在TCP中,数据的接收与发送函数是recv和send,在UDP中是recvfrom和sendto。

作用:接收数据,并获取数据来自哪里
#include
#include

ssize_t recv(int sockfd, void *buf, size_t len, int flags);

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                struct sockaddr *src_addr, socklen_t *addrlen);
参数:
    sockfd  ---- 套接字文件描述符
    buf     ---- 存放接收数据首地址
    len        ---- 想要接收数据的长度
    flags   ---- 接收送方式, 0-阻塞接收
    src_addr  --- 发送方的地址
    addrlen    --- 发送方地址的长度
返回值:
    成功: 成功接收的字节数
    失败: -1,并设置errno

作用: 指定向目标发送数据
#include
#include

ssize_t send(int sockfd, const void *buf, size_t len, int flags);

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
               const struct sockaddr *dest_addr, socklen_t addrlen);
               
参数:
    sockfd  ---- 套接字文件描述符
    buf     ---- 发送数据首地址
    len        ---- 发送数据的长度
    flags   ---- 发送方式, 0-阻塞发送
    dest_addr  --- 发送的目标地址
    addrlen    --- 地址长度
返回值:
    成功: 发送成功的字节数
    失败: -1,并设置errno

3.代码示例

3.1头文件

#ifndef __NET_H__ #define __NET_H__  #include  #include  #include  #include  #include  #include  #include  #include   typedef struct sockaddr SA; typedef struct sockaddr_in SAI;  #endif

3.2服务器代码

#include  #include "net.h"  int main(int argc, char *argv[]) {      //1. 创建套接字     int sockfd = socket(AF_INET, SOCK_DGRAM, 0);     if (sockfd < 0) {         perror("socket");         return -1;     }     printf("socket success!\n");      //2. 绑定本机地址和端口     struct SAI srvaddr = {         .sin_family = AF_INET,         .sin_port   = htons(8686),         .sin_addr.s_addr = htonl(INADDR_ANY)    //0.0.0.0     };     if (0 > bind(sockfd, (SA *)&srvaddr, sizeof(srvaddr))) {         perror("bind");         return -1;     }     printf("bind success!\n");      char buf[1024];     int ret;     SAI cliaddr;       int addrlen = sizeof(cliaddr);     while (1) {         //3. 接收数据         memset(buf, 0, sizeof(buf));         ret = recvfrom(sockfd, buf, sizeof(buf), 0, (SA*)&cliaddr, &addrlen);         if (ret < 0) {             perror("recvfrom");             break;         }         printf("Recv: %s data: %s\n", inet_ntoa(cliaddr.sin_addr), buf);          //4. 发送数据         ret = sendto(sockfd, buf, ret, 0, (SA*)&cliaddr, addrlen);         if (ret < 0) {             perror("sendto");             break;         }         if (strstr(buf, "quit"))             break;     }      //5. 关闭套接字     close(sockfd);      return 0; } 

3.3客户端代码

#include  #include "net.h"  int main(int argc, char *argv[]) {      //1. 创建数据报套接字     int sockfd = socket(AF_INET, SOCK_DGRAM, 0);     if (sockfd < 0) {         perror("socket");         return -1;     }     printf("socket success!\n");      char buf[1024];     int ret;     SAI srvaddr = {         .sin_family = AF_INET,         .sin_port   = htons(8686),         .sin_addr.s_addr = inet_addr("192.168.6.134")     };     while (1) {         //2. 发送数据         printf("Send: ");         fgets(buf, sizeof(buf), stdin);         ret = sendto(sockfd, buf, sizeof(buf), 0, (SA*)&srvaddr, sizeof(srvaddr));         if (ret < 0) {             perror("sendto");             break;         }          //3. 接收数据         memset(buf, 0, sizeof(buf));         ret = recvfrom(sockfd, buf, sizeof(buf), 0, NULL, NULL);         if (ret < 0) {             perror("recvfrom");             break;         }         printf("Recv: %s", buf);         if (strstr(buf, "quit"))             break;     }      //4. 关闭套接字     close(sockfd);      return 0; } 

4.后续

下篇学习最常用的服务器模型,以实现一个服务器响应多个客户端的需求。

        循环服务器:在同一个时刻只能响应一个客户端的请求

        并发服务器: 并发服务器在同一个时刻可以响应多个客户端的请求

相关内容

热门资讯

实测交流透视挂!宝玛大厅ai智... 实测交流透视挂!宝玛大厅ai智能透视挂教程,宝玛大厅破解软件经验(本来有挂辅助)1、每一步都需要思考...
总算了解辅助器!朱雀吴江三缺一... 总算了解辅助器!朱雀吴江三缺一ai智能透视辅助挂技巧,朱雀吴江三缺一好像是有挂(有辅助挂细节)朱雀吴...
今日公布透视!九五至尊大厅ai... 今日公布透视!九五至尊大厅ai智能透视插件,九五至尊大厅有没有透视挂窍门(切实有挂技术)1、在九五至...
玩家必看科普开挂!聚闲麻将ai... 玩家必看科普开挂!聚闲麻将ai智能透视辅助挂软件,聚闲麻将总是真的有挂(有辅助挂方式)聚闲麻将能透视...
据报道开挂!旅游娱乐ai智能开... 据报道开挂!旅游娱乐ai智能开挂工具,旅游娱乐辅助工具演示(一直有挂教学)1、全新机制【旅游娱乐ai...
一分钟揭秘开挂!决胜朋来麻将a... 一分钟揭秘开挂!决胜朋来麻将ai智能透视辅助挂教程,决胜朋来麻将真是真的是有挂(有辅助挂总结)1、首...
如何分辨真伪透视!红牛ai智能... 如何分辨真伪透视!红牛ai智能透视攻略,红牛是不是有挂经验(真是有挂技术)1、操作简单,无需红牛手机...
2分钟细说辅助器!江湖大庆麻将... 2分钟细说辅助器!江湖大庆麻将ai智能透视辅助挂攻略,江湖大庆麻将竟然是真的有挂(有辅助挂头条)1、...
总算清楚透视挂!老夫子厅ai智... 总算清楚透视挂!老夫子厅ai智能透视挂技巧,老夫子厅怎么开挂课程(好像发现有挂)老夫子厅破解侠是真的...
解密关于辅助!菜鸟麻将ai智能... 解密关于辅助!菜鸟麻将ai智能透视辅助挂脚本,菜鸟麻将总是存在有挂(有辅助挂存在)1、用户打开应用后...