当前位置:网站首页>UDP receive queue and multiple initialization test
UDP receive queue and multiple initialization test
2022-07-03 02:12:00 【Potatoes, watermelon, big sesame】
This period of time is based on udp The image is always stuck in the process of data playback , Find out recv Q Full of , But I don't know the specific reason , Here we go first udp Receiving test of .
One . Normal test
send Each time the client sends 1k, Send frequency 50hz;
- recv Every time you accept 1k, Acceptance frequency 5hz;
- watch -n 1 netstat -anu Show recv The process corresponds to 8888 Port of recv Q stay 207000 To 162000 between , It won't get stuck .recv Q The upper limit of is 207000 about . By analyzing the results, we can find , When recv q After full ,recv Take it out of the queue 1k after , From the receiving and sending end 1k Enter the queue , It is recv Continue to get data from the queue , until recv Q drop to 162000 about , That is, the queue occupancy rate reaches 80% after , To accept send Data sent from the end .
Two . When recv End cnt==800 when , perform socket Reinitialize
if(cnt == 800)
{
serfd=socket(AF_INET,SOCK_DGRAM,0);
printf("serfd = %d\n",serfd);
// ret=bind(serfd,(struct sockaddr *)&seraddr,sizeof(seraddr));
}
- socket initialization
Whether implemented or not bind operation , The receiving end will get stuck , The receiving queue will be full . meanwhile /proc/pid/fd A new one will be added below socket file , Corresponding fd by 4. If you execute bind, Will return binding failure , Port occupied .
reason : After the above if After the statement ,serfd Has become 4, The corresponding is a new socket file , in other words recv There will be a new receive queue at the end , Just no data is sent to this new queue .send The data sent by the end is still sent to serfd=3 In the corresponding queue , But no one reads the queue , cause recv Q Full of . The appearance is stuck , It's actually because serfd=4 There is no data in the corresponding queue .
2. socket initialization , At the same time recvfrom Function serfd Switch to 3 This constant
In addition to the above modifications , If you put recvfrom Of serfd Change to constant 3, Although it is newly generated 4 Corresponding fd, But the data is still from 3 Get from the corresponding queue , And it won't get stuck , It's just 4 There is no data in the corresponding queue .

3、 ... and . When recv End cnt==800 when , perform socket Reinitialize
if(cnt == 800)
{
if(serfd>0) ret = close(serfd);
printf("close serfd=%d\n",ret);
serfd=socket(AF_INET,SOCK_DGRAM,0);
sleep(1);
printf("serfd = %d\n",serfd);
ret=bind(serfd,(struct sockaddr *)&seraddr,sizeof(seraddr));
}
reason :
stay cnt by 800 when , The original fd Will close ,/proc/pid/fd/ The following file 3 It will also be deleted ; after , Re execution serfd=socket(AF_INET,SOCK_DGRAM,0); after , Will apply for available fd, And this time because 3 Number fd Has been released , So I reapplied fd still 3. It's just the corresponding inode The number has changed , from 2130436 Turned into 2132215. and 8888 The port corresponds to recv Q Medium 100 many k The data is cleared directly 0, Then start accumulating new data .



The test program
- send End :
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <iostream>
// establish UDP Realize the communication between server and client
// establish socket Connect
int main()
{
// establish socket Connect
int clifd = 0;
int cnt = 0;
clifd = socket(AF_INET, SOCK_DGRAM, 0);
if (clifd < 0)
{
perror("socke failed");
return -1;
}
printf("socket success\n");
// Send a message to the server
int tolen = 0;
int ret = 0;
char buf[1024] = {0};
while (1)
{
// std::cin.getline(buf,1023);
memset(buf, 0, 1024);
cnt++;
memcpy(buf, &cnt, sizeof(int));
struct sockaddr_in seraddr = {0};
seraddr.sin_family = AF_INET;
seraddr.sin_addr.s_addr = inet_addr("192.168.61.6");
seraddr.sin_port = htons(8888);
tolen = sizeof(seraddr);
ret = sendto(clifd, buf, strlen(buf), 0, (struct sockaddr *)&seraddr, tolen);
if (ret < 0)
{
perror("sendto failed");
close(clifd);
return -1;
}
printf("sendto success, %d\n", cnt);
// Receive messages sent from the server
// ret=recvfrom(clifd,buf,sizeof(buf),0,NULL,NULL);
usleep(20000);
// if(ret<0)
// {
// perror("recvfrom failed");
// close(clifd);
// return -1;
// }
// printf("recvfrom success\n");
// printf("receive: %s\n",buf);
}
close(clifd);
return 0;
}- recv End
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <iostream>
// establish UDP Realize the communication between server and client
int main()
{
// establish socket Connect
int serfd = 0;
int cnt = 0;
serfd = socket(AF_INET, SOCK_DGRAM, 0);
printf("serfd = %d\n", serfd);
if (serfd < 0)
{
perror("socke failed");
return -1;
}
printf("socket success\n");
// binding IP Address and port information
int ret = 0;
struct sockaddr_in seraddr = {0};
seraddr.sin_family = AF_INET;
seraddr.sin_addr.s_addr = inet_addr("192.168.61.6");
seraddr.sin_port = htons(8888);
ret = bind(serfd, (struct sockaddr *)&seraddr, sizeof(seraddr));
if (ret < 0)
{
perror("bind failed");
close(serfd);
return -1;
}
printf("bind success\n");
// Receive messages sent from clients
unsigned int addrlen = 0;
char buf[1024] = {0};
struct sockaddr_in clientaddr = {0};
addrlen = sizeof(clientaddr);
while (1)
{
memset(buf, 0, 1024);
ret = recvfrom(serfd, buf, sizeof(buf), 0, (struct sockaddr *)&clientaddr, &addrlen);
if (ret < 0)
{
perror("recvfrom failed");
close(serfd);
return -1;
}
memcpy(&cnt, buf, sizeof(int));
printf("IP=%s,port=%u\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
printf("recvfrom success\n");
printf("receive: %d\n", cnt);
if (cnt == 800)
{
if (serfd > 0)
ret = close(serfd);
printf("close serfd=%d\n", ret);
sleep(5);
serfd = socket(AF_INET, SOCK_DGRAM, 0);
sleep(1);
printf("serfd = %d\n", serfd);
ret = bind(serfd, (struct sockaddr *)&seraddr, sizeof(seraddr));
}
// Send a message to the client
memset(buf, 0, sizeof(buf));
//gets(buf);
// std::cin.getline(buf,1023);
//cnt++;
//memcpy(buf,&cnt,sizeof(int));
// ret=sendto(serfd,buf,strlen(buf),0,(struct sockaddr *)&clientaddr,addrlen);
// if(ret<0)
// {
// printf("%ret = %d\n",ret);
// perror("sendto failed");
// close(serfd);
// return -1;
// }
// printf("sendto success\n");
usleep(200000);
}
close(serfd);
return 0;
}compile :
g++ recv.cpp -o recv
g++ send.cpp -o send
5、 ... and . Running order
1. preparation
start-up 6 A command window , Enter the above file directory ;
2. First in terminal#1 function recv Program , You can redirect it to other files ;
./recv > r3.txt
3. stay terminal#2 function send Program
./send
4. stay terminal#3 see rtxt Last 10 That's ok , Update every second , Mainly used to confirm cnt=800 About when ;
watch -n 1 tail -n10 r3.txt

5. stay terminal#4 see recv Corresponding pid, And then into /proc/pid/fd see socket file , And update every second , see socket Whether the document has changed ;


6. see udp Packet loss and socket Of the corresponding file inode Change or not ;
watch -n 1 "cat /proc/net/udp |grep 22B8" among 22B8 Is the port 8888 The hexadecimal representation of .
At present, packet loss 6121 individual ;2705799 At present 8888 Port correspondence socket Of documents inode Number . and /proc/pid/fd The following documents are consistent ;

7. see udp Reception queue of
watch -n 1 netstat -anu
You can see right now recv Q Keep running high .

边栏推荐
- 微信小程序開發工具 POST net::ERR_PROXY_CONNECTION_FAILED 代理問題
- Problems encountered in small program development of dark horse shopping mall
- Use go language to realize try{}catch{}finally
- 8 free, HD, copyright free video material download websites are recommended
- [camera topic] complete analysis of camera dtsi
- Answers to ten questions about automated testing software testers must see
- Hard core observation 547 large neural network may be beginning to become aware?
- 深度学习笔记(持续更新中。。。)
- Cfdiv2 Fixed Point Guessing - (2 points for Interval answer)
- Deep learning notes (constantly updating...)
猜你喜欢

Use go language to realize try{}catch{}finally

Trial setup and use of idea GoLand development tool

通达OA v12流程中心

Redis:Redis的简单使用

4. 类和对象

MySQL learning 03
![[shutter] bottom navigation bar implementation (bottomnavigationbar bottom navigation bar | bottomnavigationbaritem navigation bar entry | pageview)](/img/41/2413af283e8f1db5d20ea845527175.gif)
[shutter] bottom navigation bar implementation (bottomnavigationbar bottom navigation bar | bottomnavigationbaritem navigation bar entry | pageview)

Coroutinecontext in kotlin

微信小程序开发工具 POST net::ERR_PROXY_CONNECTION_FAILED 代理问题

How to deal with cache hot key in redis
随机推荐
Swift开发学习
In 2022, 95% of the three most common misunderstandings in software testing were recruited. Are you that 5%?
The Sandbox阐释对元宇宙平台的愿景
树形结构数据的处理
File class (check)
Wechat applet development tool post net:: err_ PROXY_ CONNECTION_ Failed agent problem
DDL basic operation
Ni visa fails after LabVIEW installs the third-party visa software
Anna: Beibei, can you draw?
[Yu Yue education] China Ocean University job search OMG reference
Processing of tree structure data
人脸识别6- face_recognition_py-基于OpenCV使用Haar级联与dlib库进行人脸检测及实时跟踪
In the face of difficult SQL requirements, HQL is not afraid
Unrecognized SSL message, plaintext connection?
Unrecognized SSL message, plaintext connection?
iptables 4层转发
《上市风云》荐书——唯勇气最可贵
Su Shimin: 25 principles of work and life
stm32F407-------DMA
easyExcel