网络编程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.后续

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

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

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

相关内容

热门资讯

法子辅助!电脑版海盗来了辅助!... 法子辅助!电脑版海盗来了辅助!分享存在有辅助app(有挂方略)1、电脑版海盗来了辅助辅助软件下载优化...
教学辅助挂!蜀山手游全自动辅助... 教学辅助挂!蜀山手游全自动辅助(辅助)果然确实有辅助工具(有挂方针)1、超多福利:超高返利,海量正版...
五分钟了解!wejoker辅助... 五分钟了解!wejoker辅助软件价格,epoker透视底牌,窍要教程(有挂解惑)该软件可以轻松地帮...
第三方辅助!欢乐达人破解器(辅... 第三方辅助!欢乐达人破解器(辅助)原来真的是有辅助神器(有挂教程)1、在欢乐达人破解器插件功能辅助器...
讲义辅助!杭州都莱游戏辅助!必... 讲义辅助!杭州都莱游戏辅助!必备是真的有辅助攻略(有挂规律)讲义辅助!杭州都莱游戏辅助!必备是真的有...
五分钟了解!wepokerpl... 五分钟了解!wepokerplus透视脚本免费,hhpoker辅助器,机巧教程(有挂秘笈)wepok...
第三方辅助挂!多乐找刺激捕鱼辅... 第三方辅助挂!多乐找刺激捕鱼辅助(辅助)切实确实有辅助脚本(有挂讲解)1、这是跨平台的多乐找刺激捕鱼...
模块辅助!潮汕汇辅助神器!详细... 模块辅助!潮汕汇辅助神器!详细真的有辅助工具(有挂解惑)1、操作简单,无需潮汕汇辅助神器手机版透视脚...
第5分钟了解!hh poker... 第5分钟了解!hh poker插件下载,hhpoker辅助器,办法教程(有挂技巧)1、hh poke...
有玩家发现!斗棋崇阳麻将辅助脚... 有玩家发现!斗棋崇阳麻将辅助脚本(辅助)一贯真的是有辅助教程(有挂秘笈)所有人都在同一条线上,像星星...