對不起,如果這是重復的。我對網路編程有點陌生,我自己還沒有找到任何幫助我理解這一點的帖子。
所以,關于這個問題的一些背景:
我正在維護/開發現有的代碼庫。我們有一個 Raspberry Pi 控制一堆硬體,其中一些是模塊化的。用 C(可能是 C )撰寫的代碼使用 IPv4 標準通過套接字(使用 socket.h)與 Windows 上的 gui 進行通信。我很確定我們沒有在 raspberry 代碼中實作多執行緒,否則會容易得多!
我的問題與一些模塊化硬體如何與代碼互動(或者更確切地說,不是)與代碼有關。沒有額外的硬體,樹莓派就在那里等待,直到 gui 發送一些東西。這就是我們希望它的行為方式。
問題是,當我們連接了這個額外的硬體時,樹莓派還需要能夠運行一些代碼來回應其與硬體上的按鈕相關聯的 IO 引腳之一。
我嘗試向 main() 中的回圈添加(各種)條件,我認為這是代碼空閑的地方,但無濟于事。我總是讓硬體或 gui 控制作業,但不能同時作業。我最終發現在該回圈末尾附近呼叫的 read() 正在阻塞。
所以現在我想弄清楚的是,如果 read() 被阻塞,如何執行一段代碼(用于硬體控制),而當它停止時如何執行另一段代碼。就像是:
(Pseudocode)
read socket
while(blocking)
{
check for hardware signal, if found, runTest();
}
{use result of read()}
main中的回圈:
while(true)
{
initPort();
while(listening)
{
openPort();
if (netOpen)
{
//puts("// Tester is connected /////////////////////////////////");
loadCalFactors();
loadCalResistors();
loadExtConf(true);
inOn(false);
outOn(false);
// Loop until client terminates connection.
initPins();
while(netOpen)
{
/*
* Moving the block to work().
*/
// oldI = i;
// i = digitalRead(iTSW);
//
// if((i ^ oldI) == 0 && oldI == 1) // TSW has been held on
// testing = true;
//
// else if((i ^ oldI) == 1 && oldI == 0)
// testing = false;
//
// if(testLoaded && usingTermCtrl && i && !testing)
// {
// RunTp(false);
// }
// else
work();
}
}
}
}
這是它阻塞的代碼:
void work()
{
char bs[1];
int n;
//socket Sockfd is blocking here, so we only briefly return to the
//loop in main right after an action
n = read(Sockfd, bs, 1);
if(n > 0)
doAct(bs[0]);
else
checkForSOT();
}
PS: I tried putting all my hardware checks in checkForSOT() (which was previously empty) already, but it didn't do any better than the loop in main.
And where the socket is being setup:
void initPort()
{
struct sockaddr_in serv_addr;
printf("Initializing Port %d\n", HOST_PORT);
listening = false;
sockListen = socket(AF_INET, SOCK_STREAM, 0);
printf("sockListen=%d\n",sockListen);
if(sockListen < 0)
{
puts("Error opening socket");
delay(1000);
}
else
{
bzero((char *)&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(HOST_PORT);
if(bind(sockListen, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) < 0)
{
puts("Error on binding");
delay(1000);
}
else
{
listen(sockListen, 1);
listening = true;
}
}
}
void openPort()
{
int clilen;
int newsockfd;
printf("\nTester waiting for connection on socket %d\n", sockListen);
clilen = sizeof(cli_addr);
// infinite wait on a connection
if((newsockfd = accept(sockListen,
(struct sockaddr *) &cli_addr, (socklen_t*) &clilen) ) < 0 )
puts("Error on accept");
else
{
if (DEBUG) debugMode = true;
netOpen = true;
Sockfd = newsockfd;
sendVersion();
netWrite("Connected\n");
sendExtConfMessage();
sendExtConf();
}
}
Most of the posts I've found on sockets blocking mention poll() and select() (along with their p- and e- upgrades(?)), but don't go into clear-enough detail on how they work for me to figure out if they are what I'm needing. I'm also not sure what it would take to change the socket to non-blocking while maintaining the same behavior.
Note: I am still trying to read through and wrap my head around Beej's guide to network programming, so if there's a specific section of that that'll help me, please be specific.
此外,如果有人知道(或可以撰寫)通過 Netbeans 12(在 Windows 10 上)設定遠程除錯樹莓派的好指南,那將是一個巨大的幫助!
uj5u.com熱心網友回復:
投票不是很難。制作一個至少每 5 毫秒運行一次的回圈。
while (running)
初始化,然后等待某事發生
struct pollfd fds = {fd, POLLIN, 0};
int rc = poll(&fds, 1, 5); // wait for fds or 5 msec
if (rc < 0) {
perror("poll");
exit(1);
} else if (rc > 0) {
if (fds.revents & POLLIN)
recv(fd); // fds is ready
}
// check button here
}
顯然,應該對錯誤情況進行更多檢查和清理。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/313378.html
