数据报套接字

  • 一、什么是数据报套接字
  • 二、基于流套接字的客户/服务器的工作流程
    • 1、服务器
    • 2、客户端
  • 三、套接字接口
    • 1、recvfrom()系统调用
    • 2、sendto()系统调用
  • 四、示例

一、什么是数据报套接字

  • socket,即套接字是一种通信机制,凭借这种机制,客户/服务器(即要进行通信的进程)系统的开发工作既可以在本地单机上进行,也可以跨网络进行。也就是说它可以让不在同一台计算机但通过网络连接计算机上的进程进行通信。也因为这样,套接字明确地将客户端和服务器区分开来。

  • 相对于流套接字,数据报套接字的使用更为简单,它是由类型SOCK_DGRAM指定的,它不需要建立连接和维持一个连接,它们在AF_INET中通常是通过UDP/IP协议实现的。它对可以发送的数据的长度有限制,数据报作为一个单独的网络消息被传输,它可能会丢失、复制或错乱到达,UDP不是一个可靠的协议,但是它的速度比较高,因为它并一需要总是要建立和维持一个连接。

二、基于流套接字的客户/服务器的工作流程

1、服务器

  • 与使用流套接字一样,首先服务器应用程序用系统调用socket()来创建一个套接安,它是系统分配给该服务器进程的类似文件描述符的资源,它不能与其他的进程共享。

  • 接下来,服务器进程会给套接字起个名字(监听),我们使用系统调用bind()来给套接字命名。然后服务器进程就开始等待客户连接到这个套接字。

  • 不同的是,然后系统调用recvfrom()来接收来自客户程序发送过来的数据。服务器程序对数据进行相应的处理,再通过系统调用sendto()把处理后的数据发送回客户程序。

与流套接字程序相比:

  • 在流套接字中的程序中,接收数据是通过系统调用read,而发送数据是通过系统调用write()来实现,而在数据报套接字程序中,这是通过recvfrom()和sendto()调用来实现的。
    使用数据报套接字的服务器程序并不需要listen()调用来创建一个队列来存储连接,也不需要accept()调用来接收连接并创建一个新的socket描述符

2、客户端

  • 基于数据报socket的客户端比服务器端简单,同样,客户应用程序首先调用socket来创建一个未命名的套接字,与服务器一样,客户也是通过sendto()和recvfrom()来向服务器发送数据和从服务器程序接收数据。

与流套接字程序相比:

  • 使用数据报套接字的客户程序并不需要使用connect()系统调用来连接服务器程序,它只要在需要时向服务器所监听的IP端口发送信息和接收从服务器发送回来的数据即可。

三、套接字接口

  • 通用套接字接口见另一篇博客——流套接字

1、recvfrom()系统调用

  • 该函数把发送给程序的信息储存在缓冲区buffer中,并记录数据来源的程序IP端口,该函数为阻塞的
int recvfrom(int sockfd, void *buffer, size_t len,int flags, struct sockaddr *src_from, socklen_t *src_len);
  • buffer用于储存接收到的数据,len指定buffer的长度,而flags在应用中通常被设置0,src_from若不为空,则记录数据来源程序的IP端口,若src_len不为空,则其长度信息记录在src_len所指向的变量中。

2、sendto()系统调用

  • 该函数把缓冲区buffer中的信息给送给指定的IP端口的程序
int sendto(int sockfd, void *buffer, size_t len, int flags, struct sockaddr *to, socklen_t tolen);
  • buffer中储存着将要发送的数据,len是buffer的长度,而flags在应用中通常被设置为0,to是要发送数据到的程序的IP端口,tolen是to参数的长度。成功时返回发送的数据的字节数,失败时返回-1。

四、示例

server.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <signal.h>int main(int arc, char **argv)
{int server_sockfd = -1;socklen_t server_len = 0;socklen_t client_len = 0;char buffer[512];ssize_t result = 0;struct sockaddr_in server_addr;struct sockaddr_in client_addr;// 创建数据报套接字server_sockfd = socket(AF_INET, SOCK_DGRAM, 0);// 设置监听的端口、IPserver_addr.sin_family = AF_INET;server_addr.sin_addr.s_addr = htonl(INADDR_ANY);server_addr.sin_port = htons(9739);server_len = sizeof(server_addr);// 绑定(命名)套接字bind(server_sockfd, (struct sockaddr *)&server_addr, server_len);// 忽略子进程停止 或 退出 的信息,子进程成为僵尸进程后将由内核去管理signal(SIGCHLD, SIG_IGN);while (1){// 接收数据,用 client_addr 来储存数据来源程序的IP端口// 函数会阻塞知道收到客户端发来的数据result = recvfrom(server_sockfd, buffer, sizeof(buffer), 0,(struct sockaddr *)&client_addr, &client_len);if (fork() == 0){// 利用子进程来处理数据buffer[0] += 'a' - 'A';// 发送处理后的数据sendto(server_sockfd, buffer, sizeof(buffer), 0, (struct sockaddr *)&client_addr, client_len);printf("%c\n", buffer[0]);// 注意,一定要关闭子进程,否则程序运行会不正常exit(0);}}// 关闭套接字close(server_sockfd);
}

client.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>#include <netinet/in.h>
#include <arpa/inet.h>int main(int argc, char **argv)
{struct sockaddr_in server_addr;socklen_t server_len = 0;int sockfd = -1;char c = 'A';// 取第一个参数的第一个字符if (argc > 1){c = argv[1][0];}// 创建数据报套接字sockfd = socket(AF_INET, SOCK_DGRAM, 0);// 设置服务器IP、端口server_addr.sin_family = AF_INET;server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");server_addr.sin_port = htons(9739);server_len = sizeof(server_addr);// 向服务器发送数据sendto(sockfd, &c, sizeof(char), 0,(struct sockaddr *)&server_addr, server_len);// 接收服务器处理后发送过来的数据,由于不关心数据来源,所以把后两个参数设为0recvfrom(sockfd, &c, sizeof(char), 0, 0, 0);printf("char from server = %c\n", c);// 关闭套接字close(sockfd);exit(0);
}

socket:数据报套接字相关推荐

  1. socket编程——upd(数据报套接字)

    ip地址 用来标记网络上的一台电脑 如何查看电脑的IP地址? 分Windows和Linux系统 Windows是ipconfig Linux是ifconfig IP地址的分类 按版本分类 Ipv4: ...

  2. 【网络编程】Socket套接字;UDP数据报套接字编程;TCP流套接字编程

    文章目录 1. 什么是网络编程 2. 网络编程中的基本概念 3. Socket套接字 4 UDP数据报套接字编程 4.1 客户端服务器交互流程 4.2 UDP版本的回显服务 4.3 英译汉服务 5. ...

  3. iOS - Socket 网络套接字

    1.Socket 套接字 所谓 Socket,通常称为 "套接字",网络应用程序通过套接字向网络发送请求或者应答网络请求.Socket 通常用于描述 IP 地址和端口,是应⽤层与 ...

  4. SOCK_DGRAM(数据报套接字)与SOCK_STREAM(流套接口)的区别

    一.SOCK_DGRAM (数据报套接字)特性: 1.分组在发送后,可能无序地到达接收端 2.分组可能丢失.如果发生丢失,不会采取任何补救的措施,而且接受端也不必知道有分租丢失. 3.数据报分组有尺寸 ...

  5. 数据报套接字服务端和客户端

    这里练习用数据报套接字来通讯. listener.c // 数据报套接字服务器(listener.c):在指定端口监听,收到数据报后关闭连接 #include <stdio.h> #inc ...

  6. 网络编程【UDP数据报套接字编程】

    目录 1.网络编程基础 1.1 为什么需要网络编程? 1.2 什么是网络编程 1.3 网络编程中的基本概念 2.Socket套接字 2.1 分类 3.UDP数据报套接字编程 3.1 DatagramS ...

  7. 1.3.1 数据报套接字编程

    1.3  实现超链接 在网络应用过程中,特别是在Web程序中,超级链接用得非常普遍.其实使用VC技术,也可以实现超级链接功能.在本节的内容中,将介绍使用Visual C++ 6.0开发一个实现超级链接 ...

  8. Socket(套接字)详解 画图+实例

    Socket概念 Socket本意为"插座",在Linux下,用于表示进程间网络通信的特殊文件类型,本质为内核借助缓冲区形成的伪文件. 既然是文件,那肯定就可以使用文件描述符引用套 ...

  9. 无连接应用程序丢包率测试/UDP丢包率测试【基于数据报套接字的网络程序设计】

    目录 一.无连接应用程序丢包率测试 二.UDP 丢包率测试服务端 三.UDP丢包率测试客户端 四.用户使用说明(输入 / 输出规定) 五.部分运行结果 六.UDP 丢包率的测试结果分析 (1)讨论服务 ...

最新文章

  1. 商汤被曝已获准在香港上市,计划筹资逾10亿美元
  2. 手把手教你怎么在linux安装c++编译器
  3. (011) java后台开发之泛型类
  4. Vue.js 2.x render 渲染函数 JSX
  5. Laravel5.6 实现后台管理登录(自定义用户表登录)
  6. thinkphp5 图片压缩旋转_PPT图片超多,如何让排版更精致?
  7. 调用AutoCAD的内置对话框
  8. C++ STL : 模拟实现STL中的关联式容器map和set
  9. 大数据在未来十年将如何发展
  10. 【Coursera】Third Week(1)
  11. android 菜鸟面单打印_Android开发的菜鸟小记
  12. C语言-求阶乘的两种方法
  13. VUE中toast的使用与开发
  14. unity 动画控制器
  15. java的jsf是什么_什么是 JSF(Java Server Faces)
  16. 郑州市高中计算机考试操作题,郑州市区中招理化生实验操作考试4月8日开考 具体流程请看清楚...
  17. 部件库,欧姆龙Plc触摸屏,三菱FX,A,Q全系列,台达,松下,西门子PLC,变频器,施耐徳按钮
  18. 设计可复用的OO软件
  19. 将网卡的bootrom代码写入主板BIOS(转)
  20. 玩转openGauss,华为杭州研究所 开源嘉年华火热报名中

热门文章

  1. Snakemake教程-01基础部分
  2. 深圳云计算培训:一个全新的世界—Linux
  3. 2022-09-04T08:56:35.000+0000 时间格式转换
  4. 数据挖掘,机器学习,统计学习的区别与联系
  5. 智能网关与服务器连接简介
  6. TCOOP-M048-降压模块-78M05
  7. 环路补偿之单零点分析 ---- 以“反相放大器”为例分析
  8. 关于子类中virtual可有可无的讨论
  9. 空间几何-向量在另外一个向量上的投影计算
  10. TCP/IP四层模型与OSI参考模型