C 多线程客户端-服务器套接字编程

发布于 2024-11-04 21:15:59 字数 3385 浏览 2 评论 0原文

我正在同一台机器上用 C 语言实现多线程客户端-服务器套接字编程,具有相同的 IP 地址,但客户端和服务器的端口不同。我在 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);
        }
}

如果我做错了,请告诉我

问候 德布

I am implementing a Multi-threaded client-server socket programming in C on the same machine with the same IP-Address but with different ports for Client and Server. I have implemented it using pthread concepts in C environment. But I can see only my Client thread is running whereas my server thread has stopped once it reached 'accept()' routine.
I am wondering what may be the problem. If any one can find out where I am making a mistake then it would be really helpful

My CLIENT code looks like this:

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

My SERVER code:

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

Please let me know if I am doing it the wrong way

Regards
Deb

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(3

七度光 2024-11-11 21:15:59

这里至少有 3 个错误:

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

如果您使用的是小端机器,您的端口号也可能会关闭,它们通常采用网络字节顺序,您应该这样做
Serv_Addr.sin_port = htons(9999); 与客户端端口相同 - htons 将短字节从主机字节序转换为网络字节序

您没有发送任何数据!您的客户端等待服务器向其发送内容。但是您的服务器不发送任何内容,它等待客户端发送内容。什么都不会发生。

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

Here's atleast 3 errors:

lwip_accept() returns a new socket descriptor, you should use that to read from the client, not read from the original server socket (note also that lwip_accept will block until someone actually connects to the server).

Your port numbers might be off too if you're on a little endian machine, they're normally in network byte order, you should do
Serv_Addr.sin_port = htons(9999); and same for the client port - htons converts the short from host endian to network endian

You're not sending any data ! Your client waits for the server to send it something. But your server doesn't send anything, it waits for the client to send something. Nothing will happen.

Check if lwip_connect fails too, and inspect errno if your environment provides it, as it might give clues to what goes wrong

苍景流年 2024-11-11 21:15:59

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

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

If you are on the same machine, the IP address 1.2.3.4 you're using is not the typical address for localhost, which should be 127.0.0.1. Unless you have actually made the IP address of the machine using a router or some other means the IP address 1.2.3.4, that address won't resolve, and even though you're trying to run the client and server on the same machine, they won't find each other since there is no way to resolve 1.2.3.4 to a given machine on the network.

Also you don't need to lock the server to a specific IP address, you can just use the constant INADDR_ANY from netinet/in.h which will bind the socket to any interface on the system. On the client side though you will still need the correct IP address, but again, if it's the localhost, you can just use 127.0.0.1.

最舍不得你 2024-11-11 21:15:59

(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() 并删除其余部分。看起来你的所有呼叫无论如何都会被阻止。

(1) It looks as if both client and server are waiting to receive something before echoing it back. Someone has to talk first.

(2) I don't see where your lwip_accept returns a new socket with which to communicate with the client. You end up doing recv/send on the listening socket.

(3) Also consider your code here:

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

You read and echo a message but never close the socket (probably wise because it is the listening socket!) and immediately loop back to block on accept again. If client doesn't connect again you will be blocked in that accept forever.

(4) You don't need those sleepms() calls. Use pthread_join() in main and just get rid of the rest. It looks like all your calls block anyway.

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