C 中发送同时接收
我在我的服务器上编写了一段代码作为多线程。
问题是,当我在另一个套接字上接收数据时,它不会发送数据。
所以如果我从客户端1向客户端2发送一些东西,客户端2只有在他自己发送一些东西时才会收到(跳出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've made a piece of code in what's on my server as multiple threads
The problem is that it doesn't send data while im receiving on the other socket.
so if i send something from to client 1 to client 2, client2 only receives if he sends something himself(jumps out of the recv function) .. how can i solve this ?
/* 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);
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
更具体地说,I/O 有几种类型。您当前正在做的事情称为阻塞 I/O。一般来说,这意味着当您调用
send
或recv
时,操作将“阻塞”直到完成。与此相反的是所谓的非阻塞 I/O。在此 I/O 模型中,如果操作无法完成,它将立即返回。通常
select
函数与此 i/o 模型一起使用。您可以在 Select 教程 中查看示例程序。完整的源代码位于页面底部。
正如其他人所指出的,您的另一个选择是使用线程。
To be a little more specific, there are a few types of I/O. What you're doing currently is called blocking i/o. In general that means that when you call
send
orrecv
the operation will "block" until it has completed.In contrast to that there is what is known as non-blocking i/o. In this i/o model an operation will return immediately if it's unable to complete. Typically the
select
function is used with this i/o model.You can see an example program here at the Select Tutorial. The full source code is at the bottom of the page.
As others have noted, your other option is to use threads.
您的代码将在
recv()
调用上阻塞。编写一个多线程应用程序,或者研究 select() 函数的使用。Your code will block on the
recv()
call. Either write a multi-threaded application, or investigate the use of the select() function.将发送和接收放在单独的线程中。
Put send and receive in separate threads.
我注意到您正在使用
perror()
(POSIX 错误函数),这让我相信您正在使用 POSIX 操作系统,这让我怀疑它是 GNU/Linux。select()
是可移植的,poll()
以 POSIX 为中心,epoll()
以 Linux 为中心。如果使用 GNU/Linux,我强烈建议避免使用select()
并使用:poll()
(如果您只轮询几十个文件描述符)epoll()< /code> 如果您需要扩展到数千个连接,它是可用的。
如果您的应用程序不需要可移植,并且没有要求禁止使用扩展,请使用
poll()
或epoll()
。一旦您了解了select()
的工作原理,您就会很高兴摆脱它,特别是对于必须扩展以服务许多客户的东西。如果需要可移植性,请查看构建配置期间是否存在
poll()
或epoll()
并使用其中之一来支持select()
。注意,
epoll()
直到 Linux 2.5(something) 才出现,所以最好习惯使用两者。I notice that you are using
perror()
(the POSIX error function), which leads me to believe you are using a POSIX operating system, which makes me suspect its GNU/Linux.select()
is portable,poll()
is POSIX centric andepoll()
is Linux centric. If using GNU/Linux, I strongly suggest avoidingselect()
and using:poll()
if you are polling only a few dozen file descriptorsepoll()
if you need to scale to thousands of connections, and its available.If your application need not be portable, and no requirement prohibits using extensions, use
poll()
orepoll()
. Once you learn howselect()
works, you'll be very happy to get rid of it, especially for something that has to scale to serve many clients.If portability is a requirement, see if either
poll()
orepoll()
exist during your build configuration and use either in favor ofselect()
.Note,
epoll()
did not appear until Linux 2.5(something), so its best to get used to using both.您应该将代码分成两个线程,一个发送器和一个接收器。
是这样的:
并发会带来一些问题,比如访问
buffer
变量。You shoud separete the code in two threads, one transmitter and one receiver.
Somewthing like this:
The concurrency will bring some issues, like access to the
buffer
variable.有两种方法可以实现您想要的目标:
1.) 在不同的线程中实现发送和接收代码。但会有一些问题,比如增加客户端数量可能会让你在处理代码时遇到麻烦。还会存在一些并发问题(如 pcent 所提到的)。
你可以选择无阻塞套接字,但我建议不要这样做,因为我希望你不想要CPU占用。
2.) 另一种方法是使用 select() 函数,它可以让您同时监视多个不同类型的套接字。有关“select()”的更多描述,您可以谷歌搜索。 :)
There are two ways of achieving the goal you want:
1.) implement the sending and receiving codes in different threads. but there will be some issues, like increasing no of clients might get you into troubles to handle the code. also there will be some some problem of concurrency (as mentioned by pcent).
you can go for no blocking sockets but i suggest not to do so, as i hope you dont want a cpu hog.
2.) The other way is to use of select() function which will let you monitor multiple sockets of different types at the same time. for more description of "select()" you can google it. :)