在C中接收时发送

时间:2010-05-31 10:52:39

标签: c sockets blocking

我已经在我的服务器上创建了一段代码作为多线程

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

所以,如果我向客户端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);
            }
        }
}

6 个答案:

答案 0 :(得分:7)

更具体一点,有几种类型的I / O.你目前所做的是阻塞i / o。一般来说,这意味着当您致电sendrecv时,操作将“阻止”直至完成。

与此相反,存在所谓的非阻塞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()”的更多说明,您可以谷歌。 :)