这次我们实现一个UDP版本的回声服务器。

用于传输数据的函数

UDP套接字不会像TCP套接字那样保持连接状态,因此每次传输数据都要添加目标地址信息。

用于传输数据的函数:

  1. 发送数据到目标服务器。
#include <sys/socket.h>ssize_t sendto(int sock, void *buff, size_t nbytes, int flags, struct sockaddr *to, socklen_t addrlen);

​ 其中to为存有目标服务器地址信息的sockaddr结构体变量的地址值。

  1. 接收来自服务器的数据。
#include <sys/socket.h>ssize_t recvfrom(int sock, void *buff, size_t nbytes, int flags, struct sockaddr *from, socklen_t *addrlen);

​ 其中from为存有发送端地址信息的sockaddr结构体变量的地址值

服务器代码

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>const int BUF_SIZE = 30;void error_handling(const char *message);// 接收一个参数,argv[1]为端口号
int main(int argc, char *argv[]) {int server_socket;char message[BUF_SIZE];ssize_t str_len;socklen_t client_addr_size;int i;struct sockaddr_in server_addr;struct sockaddr_in client_addr;if (argc != 2) {printf("Usage: %s <port>\n", argv[0]);exit(1);}server_socket = socket(PF_INET, SOCK_DGRAM, 0); // 创建IPv4 TCP socketif (server_socket == -1) {error_handling("UDP socket create error");}// 地址信息初始化memset(&server_addr, 0, sizeof(server_addr));server_addr.sin_family = AF_INET; // IPV4 地址族server_addr.sin_addr.s_addr = htonl(INADDR_ANY); // 使用INADDR_ANY分配服务器的IP地址server_addr.sin_port = htons(atoi(argv[1])); // 端口号由第一个参数设置// 分配地址信息if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(sockaddr)) == -1) {error_handling("bind() error");}while (1) {client_addr_size = sizeof(client_addr);// 读取来自客户端的数据str_len = recvfrom(server_socket, message, BUF_SIZE, 0, (struct sockaddr*)&client_addr, &client_addr_size);// 发送数据给客户端sendto(server_socket, message, str_len, 0, (struct sockaddr*)&client_addr, client_addr_size);}printf("echo server\n");return 0;
}

注:while循环内没有break语句,因此是无限循环,close函数不会执行。

客户端代码

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>const int BUF_SIZE = 30;void error_handling(const char *message);// 接收两个参数,argv[1]为IP地址,argv[2]为端口号
int main(int argc, char *argv[]) {int sock;char message[BUF_SIZE];ssize_t str_len;socklen_t addr_size;struct sockaddr_in server_addr, from_addr;if (argc != 3) {printf("Usage : %s <IP> <port>\n", argv[0]);exit(1);}sock = socket(PF_INET, SOCK_DGRAM, 0);if (sock == -1) {error_handling("socket() error");}// 地址信息初始化memset(&server_addr, 0, sizeof(server_addr));server_addr.sin_family = AF_INET; // IPV4 地址族server_addr.sin_addr.s_addr = inet_addr(argv[1]); // 服务器IP地址server_addr.sin_port = htons(atoi(argv[2])); // 服务器端口号while (1) {fputs("Insert message(q or Q to quit): ", stdout);fgets(message, BUF_SIZE, stdin);// 如果输入q或者Q,则退出if (!strcmp(message, "q\n") || !strcmp(message, "Q\n")) {break;}sendto(sock, message, strlen(message), 0, (struct sockaddr*)&server_addr, sizeof(sockaddr)); // 发送数据到服务器addr_size = sizeof(from_addr);str_len = recvfrom(sock, message, BUF_SIZE, 0, (struct sockaddr*)&from_addr, &addr_size); // 接收数据message[str_len] = 0;printf("Message from server: %s", message);}close(sock);return 0;
}

UDP地址分配

UDP地址分配应在sendto函数调用前完成:

  1. 调用bind函数。
  2. 如果调用sendto函数是发现尚未分配地址信息,则在首次调用sendto函数时给相应的套接字自动分配IP和端口。

项目代码

github

参考

《TCP/IP网络编程》

C++回声服务器_3-UDP版本相关推荐

  1. C++回声服务器_4-UDP connect版本客户端

    针对UDP套接字调用connect函数不会与对方UDP套接字建立连接,只是向UDP套接字注册目标IP和端口信息. 修改客户端代码 服务器代码不需要修改,只需修改客户端代码.调用connect函数之后, ...

  2. C++回声服务器_5-多进程版本

    服务器和客户端都是用多进程来接收和发送数据. 服务器代码 #include <cstdio> #include <cstdlib> #include <cstring&g ...

  3. epoll边缘触发_C++回声服务器_9-epoll边缘触发模式版本服务器

    epoll默认情况下是水平触发模式,这次将epoll设置为边缘触发模式来实现服务器,而客户端直接使用完美回声服务器的客户端. 服务器代码 #include #include #include #inc ...

  4. UNIX网络编程笔记(7):回射程序的UDP版本

    1.UDP简介 UDP是一个简单的传输层协议,应用进程往一个UDP套接字写入数据,随后被封装到一个UDP数据报,进而又被封装到一个IP数据报,然后发送到目的地.UDP不保证UDP数据报会最终到达目的地 ...

  5. tftp 服务器搭建测试版本ubuntu14.04

    tftp 服务器搭建测试版本ubuntu14.04 本题大部分是来自于朱有鹏老师的笔记:::::(尊重原版) 第 第 1 步:安装 tftp 安装 tftp 所需的软件.首先需要安装 tftp-hpa ...

  6. windows 2008 server R2 按服务器角色的版本对比

    按服务器角色的版本对比 关键词: = 不可用 = 部分/限制 = 完全 服务器角色 企业版 数据中心 标准版 Itanium Web Foundation HPC Active Directory证书 ...

  7. 基于epoll实现一个IO多路复用的回声服务器

    任务: 实现一个TCP server的回声服务器,功能是将客户端发送的消息原样返回,应用epoll处理事件循环实现IO多路复用.借此任务理解IO多路复用应用的开发模式. 参考资料: http://ma ...

  8. 如何查看云服务器的系统版本,如何查看云服务器系统版本

    如何查看云服务器系统版本 内容精选 换一换 用户无法查询到弹性云服务器私网IP地址信息.本问题请按照以下思路进行排查处理.查看DHCP是否为启用状态检查是否存在dhclient进程检查弹性云服务器日志 ...

  9. 简单回声服务器的实现

    文章目录 1 简单回声服务器的实现 1 简单回声服务器的实现 实现非常非常简单,而且没啥实用价值,代码如下: server.c: #include <stdio.h> #include & ...

最新文章

  1. 数据导入报错:Got a packet bigger than‘max_allowed_packet’bytes的问题
  2. python绘制坐标图_Python绘制主次坐标图
  3. python watchdog 同时检测到多个事件_python中watchdog文件监控与检测上传功能
  4. 随机生成器、thread(暂停)、清屏定义
  5. SQL Server2005的连接和配置(入门)
  6. ir2104s的自举电容_电赛必备,IR2104S半桥驱动MOS管电机驱动板(PCB工程文件+磁悬浮代码)...
  7. Android之app引导页(背景图片切换加各个页面动画效果)
  8. Java 集合系列03之 ArrayList详细介绍(源码解析)和使用示例
  9. Uncaught (in promise) DOMException 报错
  10. centos6.5卸载java,CentOS 5.2卸载自带Java1.4.2 安装JDK6
  11. yii beforeaction 如何赋值全局变量_前端如何进行用户权限管理
  12. GB2312-80 汉字机内码
  13. 本地计算机无法启动dhcp服务,Windows10无法启用dhcp服务怎么办?
  14. 极光 短信验证出现403
  15. 谐波小波matlab,基于MATLAB小波变换在电网谐波检测的仿真与研究
  16. 微信小程序学习(一):开发准备、授权与验证
  17. 宝宝智能起名,免费起名实现方案,带源码
  18. Revit翻模软件:管件二维注释比例改变和【管道翻模】
  19. 投资理财-关于打新的
  20. 2021电工杯数学建模A题 高铁牵引供电系统论文和代码

热门文章

  1. Java 知识全面总结:并发编程+JVM+设计模式+常用框架+....
  2. 不发项目奖金,程序员怒删代码,被判 5 个月!
  3. 突围 2020!程序员这样学 AI !
  4. TCP/IPICMP报文的分类
  5. 记录opencv编译过程
  6. 【干货分享】可能是东半球最全的.NET Core跨平台微服务学习资源
  7. Proxmox 使用nfs备份及存储iso
  8. 尺取法 POJ 3601 Subsequence
  9. windows十大必禁服务
  10. Flink Window基本概念与实现原理