c - C中简单套接字编程中的同步

标签 c sockets ubuntu pthreads

我想使用 api 在 C 中创建一个简单的多线程聊天应用程序。一开始,我编写了一个与客户端通信的简单服务器,但发送的订单消息存在问题。

示例输出:

在服务器中

*new_sock 套接字数:4

服务器:你好客户端

客户端:你好服务器

服务器:你好吗?

客户:

服务器:

在客户端

服务器:你好客户端

客户端:你好服务器

服务器:你好吗?

客户:

    //server code
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <netinet/in.h>
    #include <pthread.h>

void* connection_handler(void* socket_descriptor)
{

    int socket = *(int *)socket_descriptor;

    int n;

    char server_buffer[256];
    memset(server_buffer, 0, sizeof(server_buffer));

    printf("Server:");
    gets(server_buffer);

    send(socket, server_buffer, strlen(server_buffer), 0);
    memset(server_buffer, 0, sizeof(server_buffer));

    while ((n = recv(socket, server_buffer, 255, 0)) > 0)
    {
        server_buffer[n] = '\0';
        printf("Client:%s\n", server_buffer);
        memset(server_buffer, 0, sizeof(server_buffer));
        printf("Server:");
        gets(server_buffer);
        send(socket, server_buffer, strlen(server_buffer), 0);
        memset(server_buffer, 0, sizeof(server_buffer));

        n = 0;
    }

    close(socket);

    free(socket_descriptor);

    return 0;
}


int main(int argc, char *argv[])
{
    int server_sock, client_sock, portno, client_len, n;
    int *new_sock;

    struct sockaddr_in server_addr, client_addr;

    if(argc < 2)
    {
        printf("ERROR: no port provided.\n");
        exit(1);
    }

    server_sock = socket(AF_INET, SOCK_STREAM, 0);

    if(server_sock < 0)
    {
        printf("ERROR: opening socket.");
        exit(1);
    }

    portno = atoi(argv[1]);


    memset((char *)&server_addr, 0, sizeof(server_addr));


    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(portno);
    server_addr.sin_addr.s_addr = INADDR_ANY;

    if( bind(server_sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0 )
    {
        printf("ERROR: binding socket.");
        exit(1);
    }


    listen(server_sock, 5);

    pthread_t handler_thread;


    while( client_sock = accept(server_sock, (struct sockaddr *)&client_addr, &client_len) )
    {


        new_sock = malloc(sizeof(int));
        *new_sock = client_sock;

        printf("*new_sock socket number: %d\n", *new_sock);

        if( pthread_create(&handler_thread, (void *)NULL, connection_handler, (void *)new_sock) < 0)
        {
            printf("ERROR: creating thread\n");
            exit(1);
        }


    }

    pthread_join(handler_thread, NULL);

    printf("server shut down.\n");


    return 0;
}

//client code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>


int main(int argc, char* argv[])
{
    int sock_descriptor, portno, n;

    struct sockaddr_in server_addr;

    char buffer[256];

    if (argc != 2)
    {
        printf("usage: %s port\n", argv[0]);
        exit(1);
    }


    portno = atoi(argv[1]);

    sock_descriptor = socket(AF_INET, SOCK_STREAM, 0);

    if (sock_descriptor < 0)
    {
        printf("ERROR: creating socket!\n");
        exit(1);
    }


    memset((char *)&server_addr, 0, sizeof(server_addr));

    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = INADDR_ANY;
    server_addr.sin_port = htons(portno);

    if (connect(sock_descriptor, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
    {
        printf("ERROR: connecting server!\n");
        exit(1);
    }

    memset(buffer, 0, sizeof(buffer));



    while((n = recv(sock_descriptor, buffer, 255, 0)) > 0)
    {
        buffer[n] = '\0';
        printf("Server:%s\n", buffer);
        memset(buffer, 0, sizeof(buffer));
        printf("Client:");
        gets(buffer);
        send(sock_descriptor, buffer, sizeof(buffer), 0);
        memset(buffer, 0, sizeof(buffer));

    }



    if (n <= 0)
    {
        printf("ERROR: reading from socket");
        exit(1);
    }

    return 0;
}

最佳答案

在线程创建后立即加入线程,accept 是一个阻塞调用(我假设您没有修改默认行为)。然而,线程分析起来很复杂,因为在 while 循环中阻塞了接受调用,所以加入的调用甚至不会到来。

while(1)
 {
    //do something here 
    ...
    if( pthread_create(&handler_thread, (void *)NULL, connection_handler, (void *)new_sock) < 0)
    {
        printf("ERROR: creating thread\n");
        exit(1);
    }

    pthread_join(handler_thread, NULL); //Use it right after creating thread
}

关于c - C中简单套接字编程中的同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47664680/

相关文章:

c - 通用快速排序不起作用

sockets - lua http.request 返回尝试索引全局 'http'(一个 nil 值)

使用protobuf序列化消息与zeromq进行通信

c++ - 简化/优化逻辑的工具?

比较 ifdef 指令中的字符串

c - 如何正确使用 SO_KEEPALIVE 选项来检测另一端的客户端是否已关闭?

linux - 在 Ubuntu 上找不到谁设置了 http_proxy 环境变量

c++ - 对 'boost::system::system_category()' 的 undefined reference

c++ - Linux Ubuntu 14.04, boost 库和线程编译

c - 开发-C++ : 'prinft' undeclared