1

我在具有相同 IP 地址但客户端和服务器端口不同的同一台机器上用 C 语言实现多线程客户端-服务器套接字编程。我已经在 C 环境中使用 pthread 概念实现了它。但是我只能看到我的客户端线程正在运行,而我的服务器线程在到达“accept()”例程后就停止了。我想知道可能是什么问题。如果有人能找出我在哪里犯了错误,那将非常有帮助

我的客户代码如下所示:

void *client_connect(void *arg)
{

   int client_socket;
   struct sockaddr_in Serv_Addr;
   struct sockaddr_in Client_Addr;
   int addrlen=sizeof(Client_Addr);

   char send_buffer_client[] = {"server message"};
   char recv_buffer_client[1024];
   int nbytes;

   client_socket = lwip_socket(AF_INET, SOCK_STREAM, 0);
   if (client_socket < 0) ;

   memset((char *)&Serv_Addr, 0, sizeof(Serv_Addr));
   Serv_Addr.sin_family = AF_INET;
   Serv_Addr.sin_len = sizeof(Serv_Addr);
   Serv_Addr.sin_addr.s_addr = inet_addr("1.2.3.4");
   Serv_Addr.sin_port = 9999;
   memset((char *)&Client_Addr, 0, sizeof(Client_Addr));
   Client_Addr.sin_family = AF_INET;
   Client_Addr.sin_len = sizeof(Client_Addr);
   Client_Addr.sin_addr.s_addr = inet_addr("1.2.3.4");
   Client_Addr.sin_port = 5555;

   lwip_connect(client_socket, (struct sockaddr *)&Serv_Addr, sizeof(Serv_Addr));

   while (1) {

               do{
                   nbytes = lwip_recv(client_socket, recv_buffer_client, sizeof(recv_buffer_client),0);
                   if (nbytes>0) lwip_send(client_socket, send_buffer_client, sizeof(send_buffer_client), 0);

                   printf("server message = %s\n", recv_buffer_client);
               }  while (nbytes>0);

               sleep(10);

       }
       lwip_close(client_socket);
}

我的服务器代码:

void *server_connect(void *arg)
{

   int server_socket;
   struct sockaddr_in Serv_Addr;
   struct sockaddr_in Client_Addr;
   int addrlen=sizeof(Client_Addr);
   int clientfd;
   char send_buffer[] = {"Server message"};
   char recv_buffer[1024];
   int nbytes_server, client_length;

   server_socket = lwip_socket(AF_INET, SOCK_STREAM, 0);
   if (server_socket < 0)
   printf("could not create server socket");
   else
   printf("created SERVER socket");

   memset((char *)&Serv_Addr, 0, sizeof(Serv_Addr));
   Serv_Addr.sin_family = AF_INET;
   Serv_Addr.sin_len = sizeof(Serv_Addr);
   Serv_Addr.sin_addr.s_addr = inet_addr("1.2.3.4");
   Serv_Addr.sin_port = 9999;


   client_length = sizeof(Client_Addr);
   if (lwip_bind(server_socket, (struct sockaddr *)&Serv_Addr, sizeof(Serv_Addr)) < 0) {           
           printf("could not BIND");
   }

   if ( lwip_listen(server_socket, 20) != 0 ){
            printf("could not BIND");
   }
   while (1) {
                lwip_accept(server_socket, (struct sockaddr*)&Client_Addr, &client_length);                

               do{
                nbytes_server = lwip_recv(server_socket, recv_buffer, sizeof(recv_buffer),0);
                if (nbytes_server>0){lwip_send(server_socket, send_buffer, sizeof(send_buffer), 0);}

                printf("client message = %s\n", recv_buffer);
                }while(nbytes_server>0); 
                sleepms(10);
       }
       lwip_close(server_socket);
}

void main(void)
{
    pthread_t  client_thread;
    pthread_t  server_thread;

    pthread_create(&server_thread, NULL, server_connect, NULL);
    pthread_create(&client_thread, NULL, client_connect, NULL);

    while(1){
        sleepms(1);
        }
}

如果我做错了,请告诉我

问候德布

4

3 回答 3

2

这里至少有3个错误:

lwip_accept() 返回一个新的套接字描述符,您应该使用它从客户端读取,而不是从原始服务器套接字读取(还要注意 lwip_accept 将阻塞,直到有人实际连接到服务器)。

如果你在一个小端机器上,你的端口号也可能是关闭的,它们通常是网络字节顺序,你应该 Serv_Addr.sin_port = htons(9999);对客户端端口做同样的事情 - htons将短从主机端转换为网络端

你没有发送任何数据!您的客户端等待服务器发送一些东西。但是你的服务器不发送任何东西,它等待客户端发送一些东西。什么都不会发生。

检查 lwip_connect 是否也失败,并检查errno (如果您的环境提供它),因为它可能会提供出错的线索

于 2011-05-04T17:06:50.817 回答
0

如果你在同一台机器上,你使用的 IP 地址 1.2.3.4 不是 localhost 的典型地址,它应该是 127.0.0.1。除非您实际上使用路由器或其他方式将机器的 IP 地址设置为 IP 地址 1.2.3.4,否则该地址将无法解析,即使您尝试在同一台机器上运行客户端和服务器,他们不会找到彼此,因为无法将 1.2.3.4 解析到网络上的给定机器。

此外,您不需要将服务器锁定到特定的 IP 地址,您只需使用将套接字绑定到系统上任何接口的常量INADDR_ANY即可netinet/in.h。在客户端,虽然您仍然需要正确的 IP 地址,但同样,如果它是 localhost,您可以只使用 127.0.0.1。

于 2011-05-04T15:28:34.427 回答
0

(1) 看起来客户端和服务器都在等待接收某些东西,然后再回显它。必须有人先说话。

(2) 我看不到您的 lwip_accept 在哪里返回一个与客户端通信的新套接字。您最终在侦听套接字上执行接收/发送。

(3) 还要在这里考虑您的代码:

while (1)
{
    lwip_accept(server_socket, (struct sockaddr*)&Client_Addr, &client_length);

    do
    {
        nbytes_server = lwip_recv(server_socket, recv_buffer, sizeof(recv_buffer), 0);

        if (nbytes_server > 0)
        {
            lwip_send(server_socket, send_buffer, sizeof(send_buffer), 0);
        }

        printf("client message = %s\n", recv_buffer);
    }
    while (nbytes_server > 0);

    sleepms(10);
}

您阅读并回显一条消息,但从不关闭套接字(可能是明智的,因为它是侦听套接字!)并立即循环返回以再次阻止接受。如果客户端没有再次连接,您将永远被阻止接受该接受。

(4) 你不需要那些 sleepms() 调用。在 main 中使用 pthread_join() 并摆脱其余部分。无论如何,您的所有呼叫似乎都被阻止了。

于 2011-05-04T16:44:26.240 回答