前面我们写了关于TCP的客户/服务器模式,现在我们写关于UDP的客户/服务器模式。

基于TCP编写的应用程序和基于TCP编写的应用程序之间存在一些本质的差异,其原因在于这两个传输层之间的差别:UDP是无连接不可靠的数据报协议,不同于TCP提供的面向连接的可靠字节流。

我们先来说一下简单的模型:在基于UDP的应用程序中,客户不与服务器建立连接,而只是使用sendto函数给服务器发送数据报,其中必须指定目的地(即服务器)的地址作为参数。当然,在服务器端不接受来自客户的连接,只是使用recvfrom函数,等待来自某个客户的数据到达。

接下来我们来说说将要用到的两个重要的函数:

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);

其中前3个参数分别就是我们所创建的套接字描述符,指向读入或写出的缓冲区指针和读写字节数;

第4个参数我们当下暂时赋值为0;

第5个参数src_addr指向一个将由该函数在返回时填写数据报发送者的协议地址的套接字地址结构,而在该套接字地址结构中填写的字节数则放在addrlrn参数所指定的整数中返回给调用者。

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);

前三个参数和recvfrom参数一样;

第4个参数指向一个含有数据包接收者的协议地址(IP地址及端口号)的套接字地址结构,其大小同样由第6个参数决定。

注意:sendto最后一个参数是一个整数值,而recvfrom的最后一个参数是一个指向整数值的指针(即输入输出形参数)。recvfrom的最后两个参数类似于accept的最后两个参数,返回时其中套接字地址结构的内容告诉我们是谁发送了数据报(UDP)或是谁发起了连接(TCP)。sendto的最后两个参数类似于connect的最后两个参数,调用时其中套接字地址结构被我们填入数据报将发往(UDP)或与之建立连接(TCP)的协议地址。

下面我们来具体看看代码:

服务器端:

 #include <stdio.h>#include <string.h>#include <errno.h>#include<stdlib.h>#include <netinet/in.h>#include <arpa/inet.h>#include <sys/types.h>#include <sys/socket.h>void usage(const char* arg){printf("%s [ip][port\n",arg);}int main(int argc,char *argv[]){if(argc != 3){usage(argv[0]);exit(0);}int port=atoi(argv[2]);char *ip=argv[1];int sock=socket(AF_INET,SOCK_DGRAM,0);//面向数据报if(sock<0){perror("socket");exit(1);}struct sockaddr_in local;                                                                                                                                       local.sin_family=AF_INET;local.sin_port=htons(port);local.sin_addr.s_addr=inet_addr(ip);local.sin_port=htons(port);local.sin_addr.s_addr=inet_addr(ip);if(bind(sock,(struct sockaddr*)&local,sizeof(local))<0){perror("bind");                                                                                                                                             exit(2);}struct sockaddr_in client;socklen_t len=sizeof(client);char buf[1024];while(1){memset(buf,'\0',sizeof(buf));ssize_t _s =recvfrom(sock,buf,sizeof(buf)-1,0,(struct sockaddr*)&client,&len);if(_s>0){buf[_s]='\0';printf("[%s %d]#:%s",inet_ntoa(client.sin_addr),ntohs(client.sin_port),buf);}else if(_s == 0){printf("client close...\n");break;}else{//recv fail}}return 0;}

再来看看客户端:

void usage(const char* arg){printf("%s [remote_ip][remote_port\n",arg);}int main(int argc,char *argv[]){if(argc != 3){usage(argv[0]);exit(0);}int port=atoi(argv[2]);char *ip=argv[1];                                                                                                                                               int sock=socket(AF_INET,SOCK_DGRAM,0);//面向数据报if(sock<0){perror("socket");exit(1);}struct sockaddr_in remote;remote.sin_family=AF_INET;remote.sin_port=htons(port);remote.sin_addr.s_addr=inet_addr(ip);char buf[1024];while(1){printf("please enter: ");fflush(stdout);ssize_t _s=read(0,buf,sizeof(buf)-1);buf[_s]='\0';_s=sendto(sock,buf,strlen(buf),0,(struct sockaddr*)&remote,sizeof(remote));}return 0;}

运行结果如下:

上图测试是在一台主机的情况下,我们可以看到客户端发送的消息被服务端收到了,实现了基于UDP的简单通信。

转载于:https://blog.51cto.com/10706198/1782985

基于UDP的socket客户服务器编程相关推荐

  1. 基于 UDP 的 Socket 编程

    基于 UDP 的 Socket 编程 UDP的定义 •UDP 是用户数据报协议,提供的是无连接.不可靠信息传送服务.Java 主要提供了两个类来实现基于 UDP 的 Socket 编程. UDP编程的 ...

  2. recv原理、高阶版黏包解决方案、基于UDP的socket通信

    recv原理.高阶版黏包解决方案.基于UDP的socket通信 recv原理 源码解释: Receive up to buffersize bytes from the socket. 接收来自soc ...

  3. 基于Udp的Socket网络编程

    1.新建一个工作空间 Udp 添加两个工程UdpClient 和 UdpSrv 2.在工程UdpSrv中添加UdpSrv.cpp文件 代码如下: #include <Winsock2.h> ...

  4. Java 基于 UDP 实现 Socket中的多客户端通信

    这里原理同 TCP/IP 实现多客户端通信的原理是一样的,同样的 UDPClient.java 不变,与上一篇文章中描述的一致,无需修改 UDPServer.java package com.lear ...

  5. java客户端服务器聊天程序流程图_基于java的socket简单聊天编程

    socket编程: 一:什么是socket:socket是BSD UNIX的通信机制,通常称为"套接字",其英文原意是"孔"或"插座".有些 ...

  6. 基于Udp的Socket网络编程聊天程序

    1.新建一个工程区Net 在工作区中添加两个工程 NetSrv 和 NetClient 为两个工程添加库文件 (Link中) ws2_32.lib 2.在工程NetSrv中添加Server.cpp文件 ...

  7. java socket编程 聊天_基于java的socket简单聊天编程

    socket编程: 一:什么是socket:socket是BSD UNIX的通信机制,通常称为"套接字",其英文原意是"孔"或"插座".有些 ...

  8. network programming-简单的TCP客户服务器编程

    简单的TCP(Transport Control Pr)程序客户端流程:创建套接字(套接字用IP地址:端口号)表示)socket()->请求连接connect()->交换数据 send() ...

  9. 基于udp协议的p2p服务器,基于UDP协议的P2P视频系统控制机制分析

    摘要: 本文从具有一定知名度的P2P软件流量的识别和TCP-Friendly协议控制机制出发,研究了产它们之间在控制机制方面的相似性. P2P网络视频对传输的连续性和实时性要求高,但传输层协议TCP和 ...

最新文章

  1. 新浪微博的“独立”与互联网社区的“群居”
  2. python 双冒号
  3. 同一台服务器,mysql登录不了指定端口的问题
  4. 博客园使用latex编辑公式
  5. cf451E. Devu and Flowers(产生不同多重集数量)
  6. JavaWeb中验证码的实现
  7. 使用反射修改final属性
  8. MySql数据库帮助类:DbHelperMySQL
  9. Unity3D的音效相关介绍
  10. as3 greensock_GreenSock 3 Web动画:了解GSAP的新功能
  11. 微信小游戏制作坦克大战(三)添加发射炮弹按钮,主角坦克可以发射炮弹
  12. C语言利用switch的简单计算器
  13. Java的学习之路Day08
  14. Graham-Scan算法计算凸包的Python代码实现
  15. AForge.NET Framework2.25--图像视觉处理学习(五)---颜色转换
  16. 你想要的宏基因组-微生物组知识全在这(1906)
  17. 正则表达式语法及常用实例
  18. svn+ssh服务器与客户端配置方法
  19. 让我摘下星星送给你_抖音想摘下星星给你是什么歌 星球坠落原唱是谁
  20. sqrt函数实现(神奇的算法)

热门文章

  1. Rapid7警告声明:远程桌面协议(RDP)暴露数百万 Windows 终端
  2. Android onclicklistener中使用外部类变量时为什么需要final修饰【转】
  3. Akka 接收消息超时的处理_Receive Timeout
  4. 【AS3代码】隐藏原有鼠标箭头,并自定义鼠标小箭头
  5. Segment Routing — SR-MPLS
  6. Linux 操作系统原理 — 文件系统 — 管理与优化
  7. 面向 CPython GIL 的多线程编程要点
  8. Windwos 08R2_DNS+AD安装图文
  9. 社区发现算法 - Fast Unfolding(Louvian)算法初探
  10. 菜鸟学Linux 第090篇笔记 corosync+drbd+mysql