[英]Sending while receiving in C
我在我的服務器上創建了一段代碼作為多線程
問題是,當我在另一個套接字上接收時,它不會發送數據。
因此,如果我向客戶端2發送一些內容到客戶端2,則client2僅在他自己發送內容時才會收到(跳出recv函數)..我該如何解決這個問題?
/* Thread*/
while (! stop_received) {
nr_bytes_recv = recv(s, buffer, BUFFSIZE, 0);
if(strncmp(buffer, "SEND", 4) == 0) {
char *message = "Text asads \n";
rv = send(users[0].s, message, strlen(message), 0);
rv = send(users[1].s, message, strlen(message), 0);
if (rv < 0) {
perror("Error sending");
exit(EXIT_FAILURE);
}
}else{
char *message = "Unknown command \n";
rv = send(s, message, strlen(message), 0);
if (rv < 0) {
perror("Error sending");
exit(EXIT_FAILURE);
}
}
}
更具體一點,有幾種類型的I / O. 你目前所做的是阻塞i / o。 一般來說,這意味着當你調用send
或recv
,操作將“阻塞”直到它完成。
與此相反,存在所謂的非阻塞i / o。 在此i / o模型中,如果操作無法完成,則操作將立即返回。 通常, select
函數與此i / o模型一起使用。
您可以在Select Tutorial中看到示例程序。 完整的源代碼位於頁面底部。
正如其他人所說,你的另一個選擇是使用線程。
您的代碼將阻止recv()
調用。 編寫多線程應用程序,或研究select()函數的使用。
將發送和接收放在單獨的線程中。
我注意到你正在使用perror()
(POSIX錯誤函數),這讓我相信你正在使用POSIX操作系統,這讓我懷疑它的GNU / Linux。
select()
是可移植的, poll()
是以POSIX為中心的, epoll()
是以Linux為中心的。 如果使用GNU / Linux,我強烈建議避免使用select()
並使用:
poll()
如果您只輪詢幾十個文件描述符 epoll()
如果你需要擴展到數千個連接,它可用。 如果您的應用程序不需要是可移植的,並且沒有要求禁止使用擴展,請使用poll()
或epoll()
。 一旦你了解了select()
是如何工作的,你就會很樂意擺脫它,特別是對於必須擴展以服務於許多客戶的東西。
如果需要可移植性,請查看構建配置期間是否存在poll()
或epoll()
,並使用select()
。
注意, epoll()
直到Linux 2.5(某事物)才出現,因此最好習慣使用它們。
你應該用兩個線程,一個發送器和一個接收器來分配代碼。
有點這樣:
/* 1st Thread*/
while (! stop_received) {
nr_bytes_recv = recv(s, buffer, BUFFSIZE, 0);
}
/* 2nd Thread*/
while (! stop_received) {
if(strncmp(buffer, "SEND", 4) == 0) {
char *message = "Text asads \n";
rv = send(users[0].s, message, strlen(message), 0);
rv = send(users[1].s, message, strlen(message), 0);
if (rv < 0) {
perror("Error sending");
exit(EXIT_FAILURE);
}
}else{
char *message = "Unknown command \n";
rv = send(s, message, strlen(message), 0);
if (rv < 0) {
perror("Error sending");
exit(EXIT_FAILURE);
}
}
}
並發性會帶來一些問題,比如訪問buffer
變量。
有兩種方法可以實現您想要的目標:
1.)在不同的線程中實現發送和接收代碼。 但是會出現一些問題,比如不增加客戶端可能會讓你陷入麻煩來處理代碼。 還會有一些並發問題(如pcent所述)。 你可以去沒有阻塞插座,但我建議不要這樣做,因為我希望你不想要一個cpu豬。
2.)另一種方法是使用select()函數,它可以讓你同時監視不同類型的多個套接字。 有關“select()”的更多說明,您可以谷歌。 :)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.