C 中发送同时接收

发布于 2024-09-03 06:08:56 字数 862 浏览 1 评论 0原文

我在我的服务器上编写了一段代码作为多线程。

问题是,当我在另一个套接字上接收数据时,它不会发送数据。

所以如果我从客户端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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

太阳公公是暖光 2024-09-10 06:08:56

更具体地说,I/O 有几种类型。您当前正在做的事情称为阻塞 I/O。一般来说,这意味着当您调用 sendrecv 时,操作将“阻塞”直到完成。

与此相反的是所谓的非阻塞 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 or recv 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.

还给你自由 2024-09-10 06:08:56

您的代码将在 recv() 调用上阻塞。编写一个多线程应用程序,或者研究 select() 函数的使用。

Your code will block on the recv() call. Either write a multi-threaded application, or investigate the use of the select() function.

救赎№ 2024-09-10 06:08:56

将发送和接收放在单独的线程中。

Put send and receive in separate threads.

只为一人 2024-09-10 06:08:56

我注意到您正在使用 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 and epoll() is Linux centric. If using GNU/Linux, I strongly suggest avoiding select() and using:

  • poll() if you are polling only a few dozen file descriptors
  • epoll() 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() or epoll(). Once you learn how select() 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() or epoll() exist during your build configuration and use either in favor of select().

Note, epoll() did not appear until Linux 2.5(something), so its best to get used to using both.

妞丶爷亲个 2024-09-10 06:08:56

您应该将代码分成两个线程,一个发送器和一个接收器。

是这样的:

 /* 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变量。

You shoud separete the code in two threads, one transmitter and one receiver.

Somewthing like this:

 /* 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);
            }
        }
}

The concurrency will bring some issues, like access to the buffer variable.

彼岸花ソ最美的依靠 2024-09-10 06:08:56

有两种方法可以实现您想要的目标:

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. :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文