我已经在我的服务器上创建了一段代码作为多线程
问题是,当我在另一个套接字上接收时,它不会发送数据。
所以,如果我向客户端1发送一些东西到客户端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);
}
}
}
答案 0 :(得分:7)
更具体一点,有几种类型的I / O.你目前所做的是阻塞i / o。一般来说,这意味着当您致电send
或recv
时,操作将“阻止”直至完成。
与此相反,存在所谓的非阻塞i / o。在此i / o模型中,如果操作无法完成,则操作将立即返回。通常,select
函数与此i / o模型一起使用。
您可以在Select Tutorial处查看示例程序。完整的源代码位于页面底部。
正如其他人所说,你的另一个选择是使用线程。
答案 1 :(得分:2)
您的代码将在recv()
来电时阻止。编写多线程应用程序,或调查select()函数的使用。
答案 2 :(得分:1)
将发送和接收放在不同的线程中。
答案 3 :(得分:1)
我注意到你正在使用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(某事物)才出现,因此最好习惯使用它们。
答案 4 :(得分:0)
你应该用两个线程,一个发射器和一个接收器来分配代码。
有点像这样:
/* 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
变量。
答案 5 :(得分:0)
有两种方法可以实现您想要的目标:
1。)在不同的线程中实现发送和接收代码。但是会出现一些问题,比如不增加客户端可能会让你陷入麻烦来处理代码。还会有一些并发问题(如pcent所述)。 你可以不用阻塞插座,但我建议不要这样做,因为我希望你不要一个cpu猪。
2.)另一种方法是使用select()函数,它可以让你同时监视不同类型的多个套接字。有关“select()”的更多说明,您可以谷歌。 :)