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

时间:2017-12-06 00:01:40

标签: 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;
}

1 个答案:

答案 0 :(得分: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
}