博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UDP通讯方式
阅读量:6006 次
发布时间:2019-06-20

本文共 4254 字,大约阅读时间需要 14 分钟。

hot3.png

简介

一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,它一旦把应用的程序发送给网络层之后不保留数据的备份。但是因为没有很多安全性的校验使得它的传输速率特别的快。 UDP提供了无连接通信,且不对传送数据包进行可靠性保证,适合于一次传输少量数据,UDP传输的可靠性由应用层负责。

###所需的结构和方法 *sockaddr_in结构体

#include 
struct sockaddr_in { short sin_family; // e.g. AF_INET unsigned short sin_port; // e.g. htons(3490) struct in_addr sin_addr; // see struct in_addr, below char sin_zero[8]; // zero this if you want to};struct in_addr { unsigned long s_addr; // load with inet_aton()};
  • sockaddr_in不管是tcp和UDP通讯都必然需要的一个结构。AF_INET是internet地址族,包括了tcp、udp什么的,
  • sin_port 通讯的端口
  • sin_addr 保留了通讯的IP地址
  • sin_zero 没有实际意义,只是为了 跟SOCKADDR结构在内存中对齐 ####socket方法

socket(int socket_family, int socket_type, int protocol);

  • domain

AF_UNIX,AF_LOCAL 本地通讯

AF_INET IPV4网络规约

AF_INET6 IPV6网络规约

  • type

SOCK_STREAM 提供可靠的连接方式(TCP)

SOCK_DGRAM 提供不可靠非连接的通讯方式(UDP)

  • protocol

IPPROTO_IP 相当于指定的参数为零

IPPROTO_TCP 表明采用TCP规约

IPPROTO_UDP 表示采用UDP规约

####bind方法 bind标准定义是指绑定一个名称到socket,sockfd是表示一个socket所创建的对象,sockaddr表示是该绑定的地址和socket所指向的地址分配空间大小

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

####recvfrom 接收一个数据报并保存源地址

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

  • ssockfd:标识一个已连接套接口的描述字。
  • buf:接收数据缓冲区。
  • len:缓冲区长度。
  • flags:调用操作方式。
  • src_addr:(可选)指针,指向装有源地址的缓冲区。
  • addrlen:(可选)指针,指向from缓冲区长度值。

该函数返回接收的字节数,如果出现错误返回-1,倘若对方关闭链路则返回0;

服务端

socket()->bind()->recvfrom()->sendto()

#include 
#include
#include
#include
#include
#define BUFLEN 512//最大的缓冲长度 #define PORT 8888//监听数据的端口void die(char *s){ perror(s); exit(1);}int main(int argc, char const* argv[]){ struct sockaddr_in si_me,si_other; int s,i,slen=sizeof(si_other),recv_len; char buf[BUFLEN]; //创建一个UDP的socket if((s=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP))==-1){ die("socket"); } //将这个结构清零 memset((char *)&si_me,0,sizeof(si_me)); si_me.sin_family=AF_INET; si_me.sin_port=htons(PORT); si_me.sin_addr.s_addr=htonl(INADDR_ANY); //指定需要绑定的端口 if(bind(s,(struct sockaddr*)&si_me,sizeof(si_me))==-1){ die("bind"); } while(1){ printf("Waiting for data..."); fflush(stdout); //从远程接收数据,这是一个堵塞的函数,直到接触到数据为止 if((recv_len=recvfrom(s,buf,BUFLEN,0,(struct sockaddr*)&si_other,&slen))==-1) { die("recvfrom()"); } //打印客户端的信息及其相关的信息 printf("Received packet from %s:%d\n",inet_ntoa(si_other.sin_addr),ntohs(si_other.sin_port)); printf("recv Data:%s\n",buf); //将接收到的数据进行发送 if(sendto(s,buf,recv_len,0,(struct sockaddr*)&si_other,slen)==-1){ die("sendto()"); } //重置所有的数据 bzero(&buf,sizeof(buf)); } close(s);//关闭socket return 0;}

Waiting for data...Received packet from 127.0.0.1:64687

recv Data:send data

client端

socket()->sendto()/recvfrom()

#include 
#include
#include
#include
#include
#define SERVER "127.0.0.1"#define BUFLEN 512//缓冲区的大小#define PORT 8888//发送数据的端口void die(char *s){ perror(s); exit(1);}int main(int argc, char const* argv[]){ struct sockaddr_in si_other; int s,i,slen=sizeof(si_other); char buf[BUFLEN]; char message[BUFLEN]; if((s=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP))==-1) { die("socket"); } memset((char *)&si_other,0,sizeof(si_other)); si_other.sin_family=AF_INET; si_other.sin_port=htons(PORT); if(inet_aton(SERVER,&si_other.sin_addr)==0){ fprintf(stderr,"inet_atom() failed\n"); exit(1); } while(1){ printf("Enter message:"); gets(message); //发送数据 if(sendto(s,message,strlen(message),0,(struct sockaddr *)&si_other,slen)==-1){ die("sendto()"); } //接收发送的返回消息并且打印 //再将这个buffer进行清空 if(recvfrom(s,buf,BUFLEN,0,(struct sockaddr *)&si_other,&slen)==-1){ die("recvfrom()"); } puts(buf); bzero(&buf,sizeof(buf)); } close(s); return 0;}

warning: this program uses gets(), which is unsafe.

Enter message:send data

send data

Enter message:

转载于:https://my.oschina.net/u/215677/blog/625455

你可能感兴趣的文章
自己动手构造编译系统:编译、汇编与链接2.5 链接程序的设计
查看>>
Serverless日志处理挑战与方案
查看>>
Apache Common Math Stat
查看>>
Intellij idea配置scala开发环境
查看>>
《C++语言基础》实践项目——运算符重载(一)
查看>>
ios9 HTTPS
查看>>
天猫技术全面打造『身临其境』的消费者交互体验
查看>>
[实践] Android5.1.1源码 - 让某个APP以解释执行模式运行
查看>>
快学Java SE8--Java8函数式编程(一)
查看>>
mysql到elasticsearch数据迁移踩坑实践-Ali0th
查看>>
node 异步编程
查看>>
在AWS Lambda上运行脚本语言:PHP、Ruby和Go(外文翻译)
查看>>
Objective-C与JavaScript交互初探
查看>>
代理模式
查看>>
Android内存优化全解析
查看>>
从EventBus学习扩展Weex事件机制
查看>>
VSCode前端开发神器工具
查看>>
【PPT已更新】360互联网技术训练营第九期——360容器技术解密与实践
查看>>
Python轻量级数据分析库DaPy
查看>>
揭开react hook神秘面纱
查看>>