使用 UDP 中断 while()-循环
Break while()-loop using UDP
是否可以在while()
循环中执行一些工作,例如递增计数器,然后用UDP消息中断此while()
循环?
我有一个Raspberry Pi 4,它被设置为UDP服务器。我使用的编程语言是C++。UDP.hpp:
#pragma once
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <string>
#include <iostream>
#include <cstring>
#include <sys/types.h>
#include <netdb.h>
using namespace std;
/////GLOBAL CONSTANTS/////
const int c_PORT = 8080;
class UDP
{
private:
int fdSocketUDP_; //File descriptor for UDP socket
int ClientAddressLength_; //Length of client address
struct sockaddr_in ServerAddress_; //Struct handling internet address for server
struct sockaddr_in ClientAddress_; //Struct handling internet address for client
public:
UDP(); //Initialize and bind socket
~UDP(); //Close socket
string readUDP(const int readSize); //Read via UDP protocol (Only for blocking socket)
void writeUDP(string message); //Write via UDP protocol (Only for blocking socket)
};
UDP.cpp:
#include "udp.hpp"
UDP::UDP()
{
if ((fdSocketUDP_ = socket(AF_INET, SOCK_DGRAM, 0)) < 0) //Create UDP socket
{
perror("Error - socket creation - udp.cpp");
exit(EXIT_FAILURE);
}
memset(&ServerAddress_, 0, sizeof(ServerAddress_)); //Sets ServerAddress_ to 0
memset(&ClientAddress_, 0, sizeof(ClientAddress_)); //Sets ClientAddress_ to 0
ServerAddress_.sin_family = AF_INET; //Address family, must be AF_INET = IPv4
ServerAddress_.sin_port = htons(c_PORT); //PORT number, convert PORT number to network byte order using htons()
ServerAddress_.sin_addr.s_addr = INADDR_ANY; //IP-Address of host (server IP), INADDR_ANY gets this IP Address
if (bind(fdSocketUDP_, (const struct sockaddr *)&ServerAddress_, sizeof(ServerAddress_)) < 0) //Bind the socket to ServerAddress_
{
perror("Error - socket bind - udp.cpp");
exit(EXIT_FAILURE);
}
}
UDP::~UDP()
{
close(fdSocketUDP_); //Close socket
}
string UDP::readUDP(const int readSize)
{
char readMsg[readSize] = {0}; //Read buffer
ClientAddressLength_ = sizeof(ClientAddress_);
if ((recvfrom(fdSocketUDP_, readMsg, readSize, 0, (struct sockaddr *)&ClientAddress_, (socklen_t *)&ClientAddressLength_)) < 0) //Receive data via UDP protocol
{
perror("Error - recvfrom - udp.cpp");
exit(EXIT_FAILURE);
}
string str(readMsg); //Convert char array to string
str = str.substr(0, readSize); //Make sure the string is the length of readsize
return str;
}
void UDP::writeUDP(string message)
{
//Make char array
int writeSize = message.size();
char writeMsg[writeSize + 1] = {' '};
//Convert string message to char array
for (int i = 0; i < writeSize; i++)
{
writeMsg[i] = message[i];
}
if ((sendto(fdSocketUDP_, writeMsg, writeSize, 0, (const struct sockaddr *)&ClientAddress_, (socklen_t)ClientAddressLength_)) < 0) //Send data via UDP protocol
{
perror("Error - sendto - udp.cpp");
exit(EXIT_FAILURE);
}
}
我有一台笔记本电脑,运行Labview程序。它充当 UDP 客户端。通过从笔记本电脑向 RPi 发送数据,我希望能够通过 UDP 发送特定数据来打破main()
函数中的 while 循环。
假设我从笔记本电脑向 RPi 发送"111"数据。然后,RPi 进入main()
函数中的while()
循环,做一些工作。我希望 RPi 保持在这个while()
循环中,直到我从笔记本电脑发送特定数据。假设我想打破这个while()
循环的数据是"999"。
使用 UDP 可以这样做吗?
当然。只需将套接字设置为非阻塞,并定期检查套接字上是否收到数据。如果有,请检查它是否是停止命令,如果是,则停止。您可以检查循环的每次迭代,或者,如果循环重复得非常快,则每 10 次或每 100 次迭代一次。
多亏了洛恩和@David施瓦茨的@Marquis,我解决了我的问题。解决方案是使用 fcntl 并将套接字设置为非阻塞。
我已将 UDP.hpp 更新为:
#pragma once
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <string>
#include <iostream>
#include <cstring>
#include <sys/types.h>
#include <netdb.h>
#include <sys/unistd.h>
#include <sys/fcntl.h>
using namespace std;
/////GLOBAL CONSTANTS/////
const int c_PORT = 8080;
class UDP
{
private:
int fdSocketUDP_; //File descriptor for UDP socket
int ClientAddressLength_; //Length of client address
struct sockaddr_in ServerAddress_; //Struct handling internet address for server
struct sockaddr_in ClientAddress_; //Struct handling internet address for client
public:
UDP(); //Initialize and bind socket
~UDP(); //Close socket
void initNonBlock(); //Initialize and bind socket (non blocking)
void initBlock(); //Initialize and bind socket (blocking)
void closeSocket(); //Close socket
string readNonBlock(const int readSize); //read via UDP protocol with non blocking socket
string readUDP(const int readSize); //Read via UDP protocol (Only for blocking socket)
void writeUDP(string message); //Write via UDP protocol (Only for blocking socket)
};
我已将 UDP.cpp 更新为:
#include "udp.hpp"
UDP::UDP()
{
}
UDP::~UDP()
{
closeSocket();
}
void UDP::initNonBlock()
{
if ((fdSocketUDP_ = socket(AF_INET, SOCK_DGRAM, 0)) < 0) //Create UDP socket
{
perror("Error - socket creation - udp.cpp");
exit(EXIT_FAILURE);
}
fcntl(fdSocketUDP_, F_SETFL, O_NONBLOCK); //Set to non-blocking mode
memset(&ServerAddress_, 0, sizeof(ServerAddress_)); //Sets ServerAddress_ to 0
memset(&ClientAddress_, 0, sizeof(ClientAddress_)); //Sets ClientAddress_ to 0
ServerAddress_.sin_family = AF_INET; //Address family, must be AF_INET = IPv4
ServerAddress_.sin_port = htons(c_PORT); //PORT number, convert PORT number to network byte order using htons()
ServerAddress_.sin_addr.s_addr = INADDR_ANY; //IP-Address of host (server IP), INADDR_ANY gets this IP Address
if (bind(fdSocketUDP_, (const struct sockaddr *)&ServerAddress_, sizeof(ServerAddress_)) < 0) //Bind the socket to ServerAddress_
{
perror("Error - socket bind - udp.cpp");
exit(EXIT_FAILURE);
}
}
void UDP::initBlock()
{
if ((fdSocketUDP_ = socket(AF_INET, SOCK_DGRAM, 0)) < 0) //Create UDP socket
{
perror("Error - socket creation - udp.cpp");
exit(EXIT_FAILURE);
}
memset(&ServerAddress_, 0, sizeof(ServerAddress_)); //Sets ServerAddress_ to 0
memset(&ClientAddress_, 0, sizeof(ClientAddress_)); //Sets ClientAddress_ to 0
ServerAddress_.sin_family = AF_INET; //Address family, must be AF_INET = IPv4
ServerAddress_.sin_port = htons(c_PORT); //PORT number, convert PORT number to network byte order using htons()
ServerAddress_.sin_addr.s_addr = INADDR_ANY; //IP-Address of host (server IP), INADDR_ANY gets this IP Address
if (bind(fdSocketUDP_, (const struct sockaddr *)&ServerAddress_, sizeof(ServerAddress_)) < 0) //Bind the socket to ServerAddress_
{
perror("Error - socket bind - udp.cpp");
exit(EXIT_FAILURE);
}
}
void UDP::closeSocket()
{
close(fdSocketUDP_); //Close socket
}
string UDP::readNonBlock(const int readSize)
{
char readMsg[readSize] = {0}; //Read buffer
ClientAddressLength_ = sizeof(ClientAddress_);
recvfrom(fdSocketUDP_, readMsg, readSize, 0, (struct sockaddr *)&ClientAddress_, (socklen_t *)&ClientAddressLength_);
string str(readMsg); //Convert char array to string
str = str.substr(0, readSize); //Make sure the string is the length of readsize
return str;
}
string UDP::readUDP(const int readSize)
{
char readMsg[readSize] = {0}; //Read buffer
ClientAddressLength_ = sizeof(ClientAddress_);
if ((recvfrom(fdSocketUDP_, readMsg, readSize, 0, (struct sockaddr *)&ClientAddress_, (socklen_t *)&ClientAddressLength_)) < 0) //Receive data via UDP protocol
{
perror("Error - recvfrom - udp.cpp");
exit(EXIT_FAILURE);
}
string str(readMsg); //Convert char array to string
str = str.substr(0, readSize); //Make sure the string is the length of readsize
return str;
}
void UDP::writeUDP(string message)
{
//Make char array
int writeSize = message.size();
char writeMsg[writeSize + 1] = {' '};
//Convert string message to char array
for (int i = 0; i < writeSize; i++)
{
writeMsg[i] = message[i];
}
if ((sendto(fdSocketUDP_, writeMsg, writeSize, 0, (const struct sockaddr *)&ClientAddress_, (socklen_t)ClientAddressLength_)) < 0) //Send data via UDP protocol
{
perror("Error - sendto - udp.cpp");
exit(EXIT_FAILURE);
}
}
多亏了这一点,我才能够打破 do-while 循环:
udp.closeSocket();
udp.initNonBlock();
do
{
//Do something
} while (udp.readNonBlock(3).compare("153") != 0);
udp.closeSocket();
udp.initBlock();
如果从 UDP 客户端发送的消息是"153",则会中断 do-while 循环。
相关文章:
- 我正在使用嵌套的while循环来解析具有多行的文本文件,但由于某种原因,它只通过第一行,我不知道为什么
- while循环中while循环的时间复杂度是多少
- 在while循环中输入带有std::cin的字符串后,控制台会输出大量胡言乱语
- 擦除while循环中迭代的元素
- 为什么我不能在 while 循环中创建线程?
- 退出简单while循环时出现问题
- 如果条件为TRUE(最佳方式?),则在do while循环中后置增量
- 即使没有满足他们的条件,我也无法通过一些 do-while 循环
- 嵌套While循环不起作用(C++问题)
- 如何通过替换顺序代码的while循环来添加OpenMP for循环
- 使用 GMP 的 while 循环出现问题
- 程序以使用 C++ 中的 while 循环查找一组数字的最小值
- 为什么在 while 循环中返回表达式不起作用
- 如何使用 do while 循环确定最高值和最低值
- 如何读取单个字符并在输入两个字符序列时输出? 使用 while 循环和C++
- 用于在 C++ 中使用 while 循环查找下一个素数的简单函数
- OpenCV QT,显示视频的帧(不使用while循环)
- 输入循环 while 函数
- c++中的循环(while)
- 为什么这段代码没有循环(while)