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

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

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

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

相关内容

热门资讯

每日必备透视挂!微信微乐辅助免... 每日必备透视挂!微信微乐辅助免费,小程序微乐辅助器免费版-一直真的是有辅助器1、点击下载安装,微信微...
实测揭晓辅助!微信小程序微乐辅... 您好,微信小程序微乐辅助器教程这款游戏可以开挂的,确实是有挂的,需要了解加去威信【136704302...
1.9分钟了解透视挂!微信小程... 1.9分钟了解透视挂!微信小程序微乐辅助器教程,微信微乐挂有没有-一贯存在有辅助软件1、不需要AI权...
发现一款辅助!微信微乐辅助免费... 发现一款辅助!微信微乐辅助免费,微乐兰州麻将小程序辅助-确实是真的有辅助挂1、许多玩家不知道微信微乐...
重大来袭开挂!微乐小程序辅助工... 重大来袭开挂!微乐小程序辅助工具,微信微乐小程序辅助软件-好像真的有辅助app1)微乐小程序辅助工具...
玩家必备科技辅助!微信微乐小程... 玩家必备科技辅助!微信微乐小程序游戏辅助脚本,微乐山西威信小程序-总是是有辅助神器微信微乐小程序游戏...
盘点几款透视挂!小程序微乐游戏... 盘点几款透视挂!小程序微乐游戏辅助器,微乐小程序脚本-其实有辅助技巧1.小程序微乐游戏辅助器 选牌创...
分辨真假辅助!微乐小程序开挂黑... 分辨真假辅助!微乐小程序开挂黑科技,微信小程序微乐修改器-都是存在有辅助教程1、不需要AI权限,帮助...
查到实测透视挂!微信小程序微乐... 查到实测透视挂!微信小程序微乐辅助器,小程序跑得快的技巧-原来真的是有辅助教程1、超多福利:超高返利...
关于透视挂!微信小程序微乐辅助... 关于透视挂!微信小程序微乐辅助器,微乐自建房黑科技辅助工具下载-真是是有辅助技巧该软件可以轻松地帮助...