套接字编程(二)UDP服务端与客户端的通信模拟实现
创始人
2024-05-13 01:21:07
0

目录

一、前言

二、UDP客户端流程信息

1、创建套接字

2、为套接字绑定地址信息(不推荐)

3、发送数据(将数据放入发送缓冲区中)

4、接收数据(从socket结构体接收缓冲区中取出数据)

5、关闭套接字

三、UDP客户端通信简单模拟实现

1、创建套接字

 2、为套接字绑定地址信息

3、发送数据

4、接收数据

 5、功能函数代码

6、主main函数

7、makefile

 四、UDP通信具体操作

1、使用ifconfig了解虚拟机ip  端口推荐选择10000以上

 2、创建俩个会话(一个用来运行服务端程序,一个用来运行客户端程序)

 3、创建服务端

 4、创建客户端

 5、客户端发送问候hello

 6、服务端收到hello  回复hi

 7、客户端收到服务端回复hi


一、前言

上一篇学习UDP服务端搭建的博文,也都是近一个周前写的博客了,当时对UDP通信展开了初步学习,清楚了网络通信的基本原理,练习掌握了关于网络通信的部分接口,应用实现了关于UDP服务端的搭建

关于服务端大致流程分为

1、创建套接字(在内核中创建一个socket结构体)

2、为套接字绑定地址信息(给创建的套接字内部描述源端IP和端口)

3、从socket结构体中的接收缓冲区中取出数据

4、将数据写入socket结构体中的发送缓冲区中

5、关闭套接字

 这一篇博文大概就是完成UDP通信的另一阶段,对于客户端通信的创建与模拟实现。

二、UDP客户端流程信息

具体流程如下:

1、创建套接字

建立内核与网卡之间的联系,在内核中创建一个socket结构体(struct socket)

2、为套接字绑定地址信息(不推荐)

一个端口只能被一个网络进程所占用,所以如果进行信息绑定那么这一个主机就只能进行这一个进程的通信了,如果在绑定信息之后又想访问其他进程信息,就会发出端口冲突,因此并不主动推荐客户端这边主动绑定地址信息。

3、发送数据(将数据放入发送缓冲区中)

    客户端与服务器的一个小的区别就是客户端总是先进行发送请求在进行接收回复,而服务端肯定是更主动的先进行数据接收,如果有主机发出请求那么才会进行请求的回应。

4、接收数据(从socket结构体接收缓冲区中取出数据)

5、关闭套接字

三、UDP客户端通信简单模拟实现

在UDP服务端通信的搭建过程中发现,所有的实现都贯穿着套接字描述符。所以将套接字描述符sockfd作为私有成员

1、创建套接字

接口中使用到的参数(地址域信息、套接字类型、协议类型)都为默认的IPV4相关的UDP参数,(AF_INET、SOCK_DGRAM、IPPROTO_UDP)


 2、为套接字绑定地址信息

需要提供ip地址参数以及端口号信息,套接字描述符作为私有成员

 下方代码对应ipv4结构体进行各项初始化


3、发送数据
 

① ssize_t sendto(int sockfd,  void *buf,  size_t dlen,

                                int flag,  struct sockaddr *peer,  socklen_t alen);

② sockfd socket返回的套接字描述符

③ buf 发送数据的起始地址

④ dlen 发送数据的长度,从buf地址开始,发送dlen长度的数据

⑤ flag 默认为0,阻塞发送(发送缓冲区满了就等着, 当发送缓冲区有空间了进行发送)

⑥ peer 对端地址信息,描述了数据要发送给谁

        描述了信息送往哪里    (这里存放的是接收方的信息)

⑦ alen 对端地址信息长度

⑧ 返回值: 成功返回实际发送数据字节长度,失败返回-1;


4、接收数据

① ssize_t recvfrom(int sockfd,  void *buf,  size_t dlen,
                                  int flag,  struct sockaddr *peer,  socklen_t  *alen);

② sockfd socket创建的套接字描述符

③ 一块地址空间, 里面用来存放我接收得到的数据

④ dlen 接收数据的字节长度

⑤ flag 默认为0,当socket接收缓冲区为空的时候进行等待,有数据了就进行接收

⑥ peer 对端地址信息,描述了接收的数据来自哪里。(这里存放的是来自发送方的地址信息)

⑦ alen  地址信息长度,里面即存放了想要接收的数据长度也存放了实际接收的数据长度

⑧ 成功返回实际接收的数据长度,失败返回-1
 


 5、功能函数代码

  1 #include2 #include3 #include4 #include // 字节序转换接口头文件5 #include// 地址结构类型以及协议类型头文件6 #include// 套接字接口文件7 8 class UdpSocket9 {10   private:11     int _sockfd;12   public:13     UdpSocket():_sockfd(-1){}14     ~UdpSocket(){Close();}15     bool Sockte() // 创建套接字16     {17       _sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);18       if(_sockfd<0)19       {20         perror("socket error\n");21         return false;22       }23       return true;24     }25     bool Bind(const std::string& ip, uint16_t port)26     {27         struct sockaddr_in addr; // 定义一个ipv4socket结构体28         addr.sin_family = AF_INET;// 初始化addr结构体中的sin_family29         addr.sin_port = htons(port);30         addr.sin_addr.s_addr = inet_addr(ip.c_str());31         socklen_t len = sizeof(struct sockaddr_in);32         int ret = bind(_sockfd, (struct sockaddr*)&addr, len);33         if(ret<0){34           perror("bind error\n");35           return false;36         }                                                                                37         return true;38     }39     bool Recv(std::string *body, std::string *peer_ip, uint16_t *peer_port)40     {41         struct sockaddr_in peer;42         socklen_t len = sizeof(struct sockaddr_in);43         char tmp[4096]={0};44         ssize_t ret = recvfrom(_sockfd, tmp, 4096, 0, (struct sockaddr*)&peer, &len);45         if(ret<0)46         {47           perror("recv error");48           return false;                                                                  49         }50         *peer_ip = inet_ntoa(peer.sin_addr);51         *peer_port = ntohs(peer.sin_port);52         body->assign(tmp, ret); // 从tmp中取出ret长度数据,放入body中53         return true;54     }55     bool Send(const std::string &body, const std::string &peer_ip, uint16_t peer_port)56     {57         struct sockaddr_in addr;58         addr.sin_family = AF_INET;59         addr.sin_port = htons(peer_port);60         addr.sin_addr.s_addr = inet_addr(peer_ip.c_str());61         socklen_t len = sizeof(struct sockaddr_in);62         ssize_t ret = sendto(_sockfd, body.c_str(), body.size(), 0, (struct sockaddr*)&addr, len);63         if(ret < 0){64           perror("send error");65           return false;66         }67         return true;68     }69     bool Close()70     {71         if(_sockfd != -1)72         {73           close(_sockfd);74           _sockfd = -1;75         }76         return true;77     }78 };

6、主main函数

   81 int main(int argc, char* argv[])82 {83     if(argc != 3)84     {85       std::cout<<"usage: ./client.cpp 192.168.2.2 9000\n";                             86       return -1;87     }88     std::string srv_ip = argv[1];89     uint16_t srv_port = std::atoi(argv[2]);90     UdpSocket socket;91     // 1、创建套接字92     assert(socket.Sockte() == true);93     // 2、绑定套接字(不推荐)94     while(1){95     // 3、发送数据96         std::string data;97         std::cout<<"client say:";98         fflush(stdout);99         std::cin>>data;100         assert(socket.Send(data, srv_ip, srv_port) == true);101         102     // 4、接收数据103         data.clear();104         //assert(socket.Recv(&data, &srv_ip, &srv_port) == true);105         assert(socket.Recv(&data) == true);106     }107     socket.Close();108     return 0;109 }

7、makefile

 四、UDP通信具体操作

1、使用ifconfig了解虚拟机ip  端口推荐选择10000以上

使用ens33所标记的inet

绑定端口时,推荐给出10000以上

端口范围uint16_t 0~65535       

0~1023这些端口已经被知名服务器使用了,SSH(22号端口)、HTTP(80号端口)

 2、创建俩个会话(一个用来运行服务端程序,一个用来运行客户端程序)

 3、创建服务端

 4、创建客户端

 5、客户端发送问候hello

 6、服务端收到hello  回复hi

 7、客户端收到服务端回复hi

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
客厅放八骏马摆件可以吗(家里摆... 今天给各位分享客厅放八骏马摆件可以吗的知识,其中也会对家里摆八骏马摆件好吗进行解释,如果能碰巧解决你...
苏州离哪个飞机场近(苏州离哪个... 本篇文章极速百科小编给大家谈谈苏州离哪个飞机场近,以及苏州离哪个飞机场近点对应的知识点,希望对各位有...