C套接字编程-从服务器写入()将写入服务器而不是客户端

C套接字编程-从服务器写入()将写入服务器而不是客户端,c,sockets,tcp,server,client,C,Sockets,Tcp,Server,Client,我正在开发一个TCP客户机-服务器程序,该程序应该支持使用线程的多个客户机 套接字创建、连接、绑定和接受按预期工作,因为我在运行代码时没有收到任何错误。 然而,每当我试图从服务器读取代码时,代码就会进入一个无限循环,什么也没有发生 我首先尝试从服务器写入,写入结果被写入服务器的终端 客户端代码: #include <stdlib.h> #include <stdio.h> #include <stdio.h> #include <unistd.h>

我正在开发一个TCP客户机-服务器程序,该程序应该支持使用线程的多个客户机

套接字创建、连接、绑定和接受按预期工作,因为我在运行代码时没有收到任何错误。 然而,每当我试图从服务器读取代码时,代码就会进入一个无限循环,什么也没有发生

我首先尝试从服务器写入,写入结果被写入服务器的终端

客户端代码:

#include <stdlib.h>
#include <stdio.h>
#include <stdio.h>
#include <unistd.h>
#include <assert.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <dirent.h>

#define FILE_ADDR   "/dev/urandom"

int main(int argc, char *argv[]) {

    //Get command line arguments
    unsigned int port = atoi(argv[2]);
    int length = atoi(argv[3]); //Number of bytes to read
    char* buffer = malloc(length * sizeof(char)); //Buffer to hold data read from file
    char* recvBuf = malloc(10 * sizeof(char)); // Buffer to hold response from server

    struct addrinfo hints, *servinfo, *p;
    struct sockaddr_in serv_addr;
    int sockfd = -1;
    //int rv;
    //char ip[100];

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    int rv = getaddrinfo(argv[1], argv[2], &hints, &servinfo);
    if (rv != 0) {
        perror("getaddrinfo error\n");
        exit(1);
    }
    for (p = servinfo; p != NULL; p = p->ai_next) {
        //Initialize socket
        sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
        if (sockfd < 0)
            continue;
        //Initialize connection
        rv = connect(sockfd, p->ai_addr, (socklen_t) p->ai_addrlen);
        if (rv == 0)
            break;
        close(sockfd);
        sockfd = -1;
    }
    //   inet_aton(ip, &h.sin_addr);
    freeaddrinfo(servinfo);

    //Open file for reading
    FILE *fp;
    fp = fopen(FILE_ADDR, "r");
    if (fp == NULL) {
        perror("Error in file open\n");
    }
    printf("file opened\n");
    size_t numOfbytesRead = fread(buffer, sizeof(char), length, fp);
    if (numOfbytesRead != length) {
        perror("Error reading from file\n");
    }
    printf("Buffer is %s\n", buffer);

    char* ptr;
    unsigned int N = strtoul(argv[3],&ptr,10);
    int convertedNum = htonl(N);

    if (write(sockfd, &convertedNum, sizeof(unsigned int)) < 0) {   //Send number of bytes
        perror("error writing to socket");
    }
    if (write(sockfd, buffer, sizeof(buffer) < 0)) {//Send bytes read from file
        perror("error writing to socket");

    }

    printf("send is done \n");

    int bytes_read = read(sockfd, recvBuf, sizeof(recvBuf)); //Recieve response from server
    if (bytes_read <= 0) {
        perror("Error in recieving result from server\n");
    }

    unsigned int C = 0;
    sprintf(recvBuf[0], "%d", C);

    fclose(fp);
    printf("# of printable characters: %u\n", C);
    exit(0);
    free(buffer);
    free(recvBuf);

}
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <assert.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <dirent.h>

#define FILE_ADDR   "/dev/urandom"

char* readMsg(int sockfd, size_t *msgSize)
{
    *msgSize = 0;

    unsigned int length = 0;
    int bytes_read = read(sockfd, &length, sizeof(length)); //Receive number of bytes
    if (bytes_read <= 0) {
        perror("Error in receiving message from server\n");
        return NULL;
    }
    length = ntohl(length);

    char *buffer = malloc(length+1);
    if (!buffer) {
        perror("Error in allocating memory to receive message from server\n");
        return NULL;
    }

    char *pbuf = buffer;
    unsigned int buflen = length;
    while (buflen > 0) {
        bytes_read = read(sockfd, pbuf, buflen); // Receive bytes
        if (bytes_read <= 0) {
            perror("Error in receiving message from server\n");
            free(buffer);
            return NULL;
        }
        pbuf += bytes_read;
        buflen -= bytes_read;
    }

    *msgSize = length;
    return buffer;
}

int sendMsg(int sockfd, char *msg, size_t msgSize)
{
    unsigned int convertedNum = htonl(msgSize);
    if (write(sockfd, &convertedNum, sizeof(convertedNum)) < 0) { //Send number of bytes
        perror("error writing to socket");
        return -1;
    }

    if (write(sockfd, msg, msgSize) < 0) { //Send bytes
        perror("error writing to socket");
        return -1;
    }

    return 0;
}

int main(int argc, char *argv[]) {

    char* ptr;

    //Get command line arguments
    unsigned int port = atoi(argv[2]);
    unsigned int length = strtoul(argv[3], &ptr, 10); //Number of bytes to read
    char* buffer = malloc(length); //Buffer to hold data read from file

    struct addrinfo hints, *servinfo, *p;
    struct sockaddr_in serv_addr;
    int sockfd = -1;

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    int rv = getaddrinfo(argv[1], argv[2], &hints, &servinfo);
    if (rv != 0) {
        perror("getaddrinfo error\n");
        return 1;
    }
    for (p = servinfo; p != NULL; p = p->ai_next) {
        //Initialize socket
        sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
        if (sockfd < 0)
            continue;
        //Initialize connection
        rv = connect(sockfd, p->ai_addr, (socklen_t) p->ai_addrlen);
        if (rv == 0)
            break;
        close(sockfd);
        sockfd = -1;
    }
    freeaddrinfo(servinfo);

    if (sockfd == -1) {
        perror("socket create/connect error\n");
        return 1;
    }

    size_t msgSize;
    char *msg = readMsg(sockfd, &msgSize);
    if (!msg) {
        close(sockfd);
        return 1;
    }
    printf("%.*s\n", (int)msgSize, msg);
    free(msg);

    //Open file for reading
    FILE *fp = fopen(FILE_ADDR, "rb");
    if (fp == NULL) {
        perror("Error in file open\n");
        close(sockfd);
        return 1;
    }
    printf("file opened\n");

    if (fread(buffer, 1, length, fp) != length) {
        perror("Error reading from file\n");
        fclose(fp);
        close(sockfd);
        return 1;
    }
    fclose(fp);
    printf("Buffer is %.*s\n", (int)length, buffer);

    if (sendMsg(sockfd, buffer, length) != 0) {
        free(buffer);
        close(sockfd);
        return 1;
    }
    free(buffer);
    printf("send is done \n");

    msg = readMsg(sockfd, &msgSize); // response from server
    if (!msg) {
        close(sockfd);
        return 1;
    }
    printf("# of printable characters: %.*s\n", (int)msgSize, msg);
    free(msg);

    return 0;
}
服务器代码:

#include <stdlib.h>
#include <stdio.h>
#include <stdio.h>
#include <unistd.h>
#include <assert.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <dirent.h>
#include <pthread.h>
#include <signal.h>

static volatile int keepRunning = 1;
int pcc_total[159];

void intHandler(int dummy) {
    keepRunning = 0;
}

void *compute(void *socket_desc) {
    int count = 0;
    int sock = *(int*) socket_desc;
    printf("now will allocate N \n");
    int n=0;
    if (write(sock, "hi", 2) < 0) { //Send number of bytes
        perror("error writing to socket\n");
    }
    if (read(sock, &n, sizeof(unsigned int)) < 0) {
        perror("Error reading from socket\n");
        exit(1);
    }
    int N = ntohl(n);
    printf("len is %d\n", N);
    char* data = calloc(N, sizeof(char));
    int len = read(sock, data, N);
    printf("data is %s\n", data);
    if (len < 0) {
        perror("Error reading from socket\n");
        exit(1);
    }
    for (int i = 0; i < len; i++) {
        int tmp = 0;
        sprintf(data[i], "%d", tmp);
        if (tmp >= 32 & tmp <= 126) {
            count++;

            __sync_fetch_and_add(&pcc_total[tmp], 1);
        }
    }
    char scount[100];
    atoi(count);
    write(sock, count, strlen(scount));
    free(data);
    pthread_exit(NULL);
    close(sock);
    exit(0);
}

int main(int argc, char *argv[]) {

    unsigned int port = atoi(argv[1]);
    signal(SIGINT, intHandler);

    int socket_desc, client_sock, c, *new_sock;
    struct sockaddr_in server, client;
    c = sizeof(struct sockaddr_in);

    socket_desc = socket( AF_INET, SOCK_STREAM, 0);
    if (socket_desc == -1) {
        perror("Could not create socket");
        exit(1);
    }
    printf("socket created\n");
    memset(&server, 0, c);

    server.sin_family = AF_INET;
    server.sin_addr.s_addr = htonl(INADDR_ANY);
    server.sin_port = htons(port);

    if (0 != bind(socket_desc, (struct sockaddr*) &server, sizeof(server))) {
        perror("\n Error : Bind Failed \n");
        exit(1);
    }
    printf("bind created\n");
    if (0 != listen(socket_desc, 10)) {
        perror("\n Error : Listen Failed \n");
        exit(1);
    }
    printf("listen created\n");
    while (keepRunning) {
        client_sock = accept(socket_desc, (struct sockaddr *) &client,
                (socklen_t*) &c);
        if (client_sock < 0) {
            perror("\n Error : Accept Failed\n");
            exit(1);
        }
        printf("accept created\n");
        pthread_t tid;
        new_sock = malloc(100*sizeof(int));
        *new_sock = client_sock;
        if ((pthread_create(&tid, NULL, compute, (void*) new_sock)) < 0) {
            perror("could not create thread\n");
            exit(1);
        }
        printf("thread created\n");
        // close socket
        close(client_sock);
        free(new_sock);
        pthread_join(tid, NULL);
    }

    exit(0);

}
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <assert.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <dirent.h>
#include <pthread.h>
#include <signal.h>

static volatile int keepRunning = 1;
int pcc_total[159];

void intHandler(int dummy) {
    keepRunning = 0;
}

char* readMsg(int sockfd, size_t *msgSize)
{
    *msgSize = 0;

    unsigned int length = 0;
    int bytes_read = read(sockfd, &length, sizeof(length)); //Receive number of bytes
    if (bytes_read <= 0) {
        perror("Error in receiving message from server\n");
        return NULL;
    }
    length = ntohl(length);

    char *buffer = malloc(length+1);
    if (!buffer) {
        perror("Error in allocating memory to receive message from server\n");
        return NULL;
    }

    char *pbuf = buffer;
    unsigned int buflen = length;
    while (buflen > 0) {
        bytes_read = read(sockfd, pbuf, buflen); // Receive bytes
        if (bytes_read <= 0) {
            perror("Error in receiving message from server\n");
            free(buffer);
            return NULL;
        }
        pbuf += bytes_read;
        buflen -= bytes_read;
    }

    *msgSize = length;
    return buffer;
}

int sendMsg(int sockfd, char *msg, size_t msgSize)
{
    unsigned int convertedNum = htonl(msgSize);
    if (write(sockfd, &convertedNum, sizeof(convertedNum)) < 0) { //Send number of bytes
        perror("error writing to socket");
        return -1;
    }

    if (write(sockfd, msg, msgSize) < 0) { //Send bytes
        perror("error writing to socket");
        return -1;
    }

    return 0;
}

void *compute(void *socket_desc) {
    int sock = * (int*) socket_desc;
    free(socket_desc);

    if (sendMsg(sock, "hi", 2) != 0) {
        perror("error writing to socket\n");
        close(sock);
        return NULL;
    }

    size_t length = 0;
    char *data = readMsg(sock, &length);
    if (!msg) {
        close(sock);
        return NULL;
    }
    printf("len is %d\n", (int)length);
    printf("data is %.*s\n", (int)length, data);

    int count = 0;
    for (size_t i = 0; i < length; i++) {
        // ...
    }
    free(data);

    char scount[20];
    sprintf(scount, "%d", count);
    sendMsg(sock, scount, strlen(scount));

    close(sock);
    return NULL;
}

int main(int argc, char *argv[]) {

    unsigned int port = atoi(argv[1]);
    signal(SIGINT, intHandler);

    int socket_desc, client_sock, c, *new_sock;
    struct sockaddr_in server, client;

    socket_desc = socket( AF_INET, SOCK_STREAM, 0);
    if (socket_desc == -1) {
        perror("Could not create server socket");
        return 1;
    }
    printf("server socket created\n");

    memset(&server, 0, c);
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = htonl(INADDR_ANY);
    server.sin_port = htons(port);

    if (bind(socket_desc, (struct sockaddr*) &server, sizeof(server)) < 0) {
        perror("\n Error : Bind Failed \n");
        close(socket_desc);
        return 1;
    }
    printf("bind created\n");

    if (listen(socket_desc, 10) < 0) {
        perror("\n Error : Listen Failed \n");
        close(socket_desc);
        return 1;
    }
    printf("listening\n");

    while (keepRunning) {
        c = sizeof(client);
        client_sock = accept(socket_desc, (struct sockaddr *) &client,
                            (socklen_t*) &c);
        if (client_sock < 0) {
            perror("\n Error : Accept Failed\n");
            continue;
        }
        printf("client accepted\n");

        new_sock = malloc(sizeof(int));
        if (!new_sock) {
            perror("\n Error : Malloc Failed\n");
            close(client_sock);
            continue;
        }
        *new_sock = client_sock;

        pthread_t tid;
        if (pthread_create(&tid, NULL, &compute, new_sock) != 0) {
            perror("\n Error : Thread Create Failed\n");
            free(new_sock);
            close(client_sock);
            continue;
        }
        printf("thread created\n");
    }

    close(socket_desc);
    return 0;
}
我使用以下命令运行代码:

gcc-std=c99-O3-Wall-o pcc_服务器pcc_服务器.c-pthread


gcc-std=gnu99-O3-Wall-o pcc_client pcc_client.c我认为您应该删除这两行

close(client_sock);
free(new_sock);

在服务器代码中,因为如果新创建的线程在如此早的时间点被释放,它将无法在这些变量和内存区域上执行。您可以在不使用它的情况下重试代码吗?

您的服务器在启动处理该连接的线程后立即关闭连接的套接字并释放存储其文件句柄的内存。不幸的是,服务器只会因此挂起,但您有数据竞争,因此程序的行为在形式上是未定义的


由于在线程完成之前服务器不会执行任何其他操作,因此您最好在pthread_加入之后移动close和free。或者,考虑到您在创建任何其他线程之前确实加入了计算,不如同步调用compute,而不是创建一个新线程让它运行?

您的代码有很多问题

在客户端:

在调用fread时,您需要使用rb而不是r

当调用printf来输出实际读取的文件数据时,终止缓冲区或将其长度传递给printf时,不能为null。你需要这样做

将htonl的返回值指定给int而不是无符号int

调用write发送缓冲区时,您使用的是sizeofbuffer,而应该使用length或N,为什么要使用两个单独的变量来保存相同的命令行参数值?。缓冲区是一个指向使用malloc分配的内存的指针,因此sizeofbuffer与sizeofvoid*相同,这不是您想要的。此外,您甚至没有正确调用write,因为您的括号都是错误的,在发送convertedNum时,它们在上一次写调用中是正确的

同样,当调用read读取recvBuf时,您使用的是sizeofrecvBuf,而您应该使用10,sicne recvBuf也是指向malloced内存的指针

您没有读取服务器在连接时发送给客户端的hi问候语,因此您将这些字节与下一条消息的以下大小值的字节合并在一起,从而导致C值损坏

在服务器端:

您的计算线程例程向客户机发送hi问候语,但它不使用任何类型的分隔符,如在问候语前加上长度前缀,或以换行符、空字符或其他唯一字符终止问候语,以将其与任何后续数据分隔开。您应该始终以某种方式对消息进行分隔

您正在关闭已接受的套接字,并在创建用于处理该客户端的工作线程后立即释放malloced new_sock。你正在从这条线众所周知的背后撕掉记忆。当使用完套接字并释放内存时,线程需要是关闭套接字并释放内存的线程,而不是接受循环

线程确实尝试关闭套接字,但没有释放内存,但是在它首先调用pthread_exit之后,这是错误的。pthread_exit终止调用线程,因此它必须是线程调用不调用exit!的最后一件事!。事实上,甚至根本不直接调用pthread_exit,只要从compute返回,pthreads库就会为您调用pthread_exit,传递您选择返回的void*值

您的accept循环根本不应该调用pthread_join。它会阻止调用线程,直到指定的线程终止。这违背了使用线程处理客户机的全部目的,并阻止服务器一次接受多个客户机。如果您打算使用pthread_join,那么应该在accept循环结束之后,这样您就可以在退出应用程序之前等待任何可能仍在运行的工作线程。但这也意味着要跟踪pthread_创建返回的pthread_t值,这需要更多的工作

话虽如此,请尝试以下代码:

客户端代码:

#include <stdlib.h>
#include <stdio.h>
#include <stdio.h>
#include <unistd.h>
#include <assert.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <dirent.h>

#define FILE_ADDR   "/dev/urandom"

int main(int argc, char *argv[]) {

    //Get command line arguments
    unsigned int port = atoi(argv[2]);
    int length = atoi(argv[3]); //Number of bytes to read
    char* buffer = malloc(length * sizeof(char)); //Buffer to hold data read from file
    char* recvBuf = malloc(10 * sizeof(char)); // Buffer to hold response from server

    struct addrinfo hints, *servinfo, *p;
    struct sockaddr_in serv_addr;
    int sockfd = -1;
    //int rv;
    //char ip[100];

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    int rv = getaddrinfo(argv[1], argv[2], &hints, &servinfo);
    if (rv != 0) {
        perror("getaddrinfo error\n");
        exit(1);
    }
    for (p = servinfo; p != NULL; p = p->ai_next) {
        //Initialize socket
        sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
        if (sockfd < 0)
            continue;
        //Initialize connection
        rv = connect(sockfd, p->ai_addr, (socklen_t) p->ai_addrlen);
        if (rv == 0)
            break;
        close(sockfd);
        sockfd = -1;
    }
    //   inet_aton(ip, &h.sin_addr);
    freeaddrinfo(servinfo);

    //Open file for reading
    FILE *fp;
    fp = fopen(FILE_ADDR, "r");
    if (fp == NULL) {
        perror("Error in file open\n");
    }
    printf("file opened\n");
    size_t numOfbytesRead = fread(buffer, sizeof(char), length, fp);
    if (numOfbytesRead != length) {
        perror("Error reading from file\n");
    }
    printf("Buffer is %s\n", buffer);

    char* ptr;
    unsigned int N = strtoul(argv[3],&ptr,10);
    int convertedNum = htonl(N);

    if (write(sockfd, &convertedNum, sizeof(unsigned int)) < 0) {   //Send number of bytes
        perror("error writing to socket");
    }
    if (write(sockfd, buffer, sizeof(buffer) < 0)) {//Send bytes read from file
        perror("error writing to socket");

    }

    printf("send is done \n");

    int bytes_read = read(sockfd, recvBuf, sizeof(recvBuf)); //Recieve response from server
    if (bytes_read <= 0) {
        perror("Error in recieving result from server\n");
    }

    unsigned int C = 0;
    sprintf(recvBuf[0], "%d", C);

    fclose(fp);
    printf("# of printable characters: %u\n", C);
    exit(0);
    free(buffer);
    free(recvBuf);

}
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <assert.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <dirent.h>

#define FILE_ADDR   "/dev/urandom"

char* readMsg(int sockfd, size_t *msgSize)
{
    *msgSize = 0;

    unsigned int length = 0;
    int bytes_read = read(sockfd, &length, sizeof(length)); //Receive number of bytes
    if (bytes_read <= 0) {
        perror("Error in receiving message from server\n");
        return NULL;
    }
    length = ntohl(length);

    char *buffer = malloc(length+1);
    if (!buffer) {
        perror("Error in allocating memory to receive message from server\n");
        return NULL;
    }

    char *pbuf = buffer;
    unsigned int buflen = length;
    while (buflen > 0) {
        bytes_read = read(sockfd, pbuf, buflen); // Receive bytes
        if (bytes_read <= 0) {
            perror("Error in receiving message from server\n");
            free(buffer);
            return NULL;
        }
        pbuf += bytes_read;
        buflen -= bytes_read;
    }

    *msgSize = length;
    return buffer;
}

int sendMsg(int sockfd, char *msg, size_t msgSize)
{
    unsigned int convertedNum = htonl(msgSize);
    if (write(sockfd, &convertedNum, sizeof(convertedNum)) < 0) { //Send number of bytes
        perror("error writing to socket");
        return -1;
    }

    if (write(sockfd, msg, msgSize) < 0) { //Send bytes
        perror("error writing to socket");
        return -1;
    }

    return 0;
}

int main(int argc, char *argv[]) {

    char* ptr;

    //Get command line arguments
    unsigned int port = atoi(argv[2]);
    unsigned int length = strtoul(argv[3], &ptr, 10); //Number of bytes to read
    char* buffer = malloc(length); //Buffer to hold data read from file

    struct addrinfo hints, *servinfo, *p;
    struct sockaddr_in serv_addr;
    int sockfd = -1;

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    int rv = getaddrinfo(argv[1], argv[2], &hints, &servinfo);
    if (rv != 0) {
        perror("getaddrinfo error\n");
        return 1;
    }
    for (p = servinfo; p != NULL; p = p->ai_next) {
        //Initialize socket
        sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
        if (sockfd < 0)
            continue;
        //Initialize connection
        rv = connect(sockfd, p->ai_addr, (socklen_t) p->ai_addrlen);
        if (rv == 0)
            break;
        close(sockfd);
        sockfd = -1;
    }
    freeaddrinfo(servinfo);

    if (sockfd == -1) {
        perror("socket create/connect error\n");
        return 1;
    }

    size_t msgSize;
    char *msg = readMsg(sockfd, &msgSize);
    if (!msg) {
        close(sockfd);
        return 1;
    }
    printf("%.*s\n", (int)msgSize, msg);
    free(msg);

    //Open file for reading
    FILE *fp = fopen(FILE_ADDR, "rb");
    if (fp == NULL) {
        perror("Error in file open\n");
        close(sockfd);
        return 1;
    }
    printf("file opened\n");

    if (fread(buffer, 1, length, fp) != length) {
        perror("Error reading from file\n");
        fclose(fp);
        close(sockfd);
        return 1;
    }
    fclose(fp);
    printf("Buffer is %.*s\n", (int)length, buffer);

    if (sendMsg(sockfd, buffer, length) != 0) {
        free(buffer);
        close(sockfd);
        return 1;
    }
    free(buffer);
    printf("send is done \n");

    msg = readMsg(sockfd, &msgSize); // response from server
    if (!msg) {
        close(sockfd);
        return 1;
    }
    printf("# of printable characters: %.*s\n", (int)msgSize, msg);
    free(msg);

    return 0;
}
服务器代码:

#include <stdlib.h>
#include <stdio.h>
#include <stdio.h>
#include <unistd.h>
#include <assert.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <dirent.h>
#include <pthread.h>
#include <signal.h>

static volatile int keepRunning = 1;
int pcc_total[159];

void intHandler(int dummy) {
    keepRunning = 0;
}

void *compute(void *socket_desc) {
    int count = 0;
    int sock = *(int*) socket_desc;
    printf("now will allocate N \n");
    int n=0;
    if (write(sock, "hi", 2) < 0) { //Send number of bytes
        perror("error writing to socket\n");
    }
    if (read(sock, &n, sizeof(unsigned int)) < 0) {
        perror("Error reading from socket\n");
        exit(1);
    }
    int N = ntohl(n);
    printf("len is %d\n", N);
    char* data = calloc(N, sizeof(char));
    int len = read(sock, data, N);
    printf("data is %s\n", data);
    if (len < 0) {
        perror("Error reading from socket\n");
        exit(1);
    }
    for (int i = 0; i < len; i++) {
        int tmp = 0;
        sprintf(data[i], "%d", tmp);
        if (tmp >= 32 & tmp <= 126) {
            count++;

            __sync_fetch_and_add(&pcc_total[tmp], 1);
        }
    }
    char scount[100];
    atoi(count);
    write(sock, count, strlen(scount));
    free(data);
    pthread_exit(NULL);
    close(sock);
    exit(0);
}

int main(int argc, char *argv[]) {

    unsigned int port = atoi(argv[1]);
    signal(SIGINT, intHandler);

    int socket_desc, client_sock, c, *new_sock;
    struct sockaddr_in server, client;
    c = sizeof(struct sockaddr_in);

    socket_desc = socket( AF_INET, SOCK_STREAM, 0);
    if (socket_desc == -1) {
        perror("Could not create socket");
        exit(1);
    }
    printf("socket created\n");
    memset(&server, 0, c);

    server.sin_family = AF_INET;
    server.sin_addr.s_addr = htonl(INADDR_ANY);
    server.sin_port = htons(port);

    if (0 != bind(socket_desc, (struct sockaddr*) &server, sizeof(server))) {
        perror("\n Error : Bind Failed \n");
        exit(1);
    }
    printf("bind created\n");
    if (0 != listen(socket_desc, 10)) {
        perror("\n Error : Listen Failed \n");
        exit(1);
    }
    printf("listen created\n");
    while (keepRunning) {
        client_sock = accept(socket_desc, (struct sockaddr *) &client,
                (socklen_t*) &c);
        if (client_sock < 0) {
            perror("\n Error : Accept Failed\n");
            exit(1);
        }
        printf("accept created\n");
        pthread_t tid;
        new_sock = malloc(100*sizeof(int));
        *new_sock = client_sock;
        if ((pthread_create(&tid, NULL, compute, (void*) new_sock)) < 0) {
            perror("could not create thread\n");
            exit(1);
        }
        printf("thread created\n");
        // close socket
        close(client_sock);
        free(new_sock);
        pthread_join(tid, NULL);
    }

    exit(0);

}
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <assert.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <dirent.h>
#include <pthread.h>
#include <signal.h>

static volatile int keepRunning = 1;
int pcc_total[159];

void intHandler(int dummy) {
    keepRunning = 0;
}

char* readMsg(int sockfd, size_t *msgSize)
{
    *msgSize = 0;

    unsigned int length = 0;
    int bytes_read = read(sockfd, &length, sizeof(length)); //Receive number of bytes
    if (bytes_read <= 0) {
        perror("Error in receiving message from server\n");
        return NULL;
    }
    length = ntohl(length);

    char *buffer = malloc(length+1);
    if (!buffer) {
        perror("Error in allocating memory to receive message from server\n");
        return NULL;
    }

    char *pbuf = buffer;
    unsigned int buflen = length;
    while (buflen > 0) {
        bytes_read = read(sockfd, pbuf, buflen); // Receive bytes
        if (bytes_read <= 0) {
            perror("Error in receiving message from server\n");
            free(buffer);
            return NULL;
        }
        pbuf += bytes_read;
        buflen -= bytes_read;
    }

    *msgSize = length;
    return buffer;
}

int sendMsg(int sockfd, char *msg, size_t msgSize)
{
    unsigned int convertedNum = htonl(msgSize);
    if (write(sockfd, &convertedNum, sizeof(convertedNum)) < 0) { //Send number of bytes
        perror("error writing to socket");
        return -1;
    }

    if (write(sockfd, msg, msgSize) < 0) { //Send bytes
        perror("error writing to socket");
        return -1;
    }

    return 0;
}

void *compute(void *socket_desc) {
    int sock = * (int*) socket_desc;
    free(socket_desc);

    if (sendMsg(sock, "hi", 2) != 0) {
        perror("error writing to socket\n");
        close(sock);
        return NULL;
    }

    size_t length = 0;
    char *data = readMsg(sock, &length);
    if (!msg) {
        close(sock);
        return NULL;
    }
    printf("len is %d\n", (int)length);
    printf("data is %.*s\n", (int)length, data);

    int count = 0;
    for (size_t i = 0; i < length; i++) {
        // ...
    }
    free(data);

    char scount[20];
    sprintf(scount, "%d", count);
    sendMsg(sock, scount, strlen(scount));

    close(sock);
    return NULL;
}

int main(int argc, char *argv[]) {

    unsigned int port = atoi(argv[1]);
    signal(SIGINT, intHandler);

    int socket_desc, client_sock, c, *new_sock;
    struct sockaddr_in server, client;

    socket_desc = socket( AF_INET, SOCK_STREAM, 0);
    if (socket_desc == -1) {
        perror("Could not create server socket");
        return 1;
    }
    printf("server socket created\n");

    memset(&server, 0, c);
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = htonl(INADDR_ANY);
    server.sin_port = htons(port);

    if (bind(socket_desc, (struct sockaddr*) &server, sizeof(server)) < 0) {
        perror("\n Error : Bind Failed \n");
        close(socket_desc);
        return 1;
    }
    printf("bind created\n");

    if (listen(socket_desc, 10) < 0) {
        perror("\n Error : Listen Failed \n");
        close(socket_desc);
        return 1;
    }
    printf("listening\n");

    while (keepRunning) {
        c = sizeof(client);
        client_sock = accept(socket_desc, (struct sockaddr *) &client,
                            (socklen_t*) &c);
        if (client_sock < 0) {
            perror("\n Error : Accept Failed\n");
            continue;
        }
        printf("client accepted\n");

        new_sock = malloc(sizeof(int));
        if (!new_sock) {
            perror("\n Error : Malloc Failed\n");
            close(client_sock);
            continue;
        }
        *new_sock = client_sock;

        pthread_t tid;
        if (pthread_create(&tid, NULL, &compute, new_sock) != 0) {
            perror("\n Error : Thread Create Failed\n");
            free(new_sock);
            close(client_sock);
            continue;
        }
        printf("thread created\n");
    }

    close(socket_desc);
    return 0;
}

创建线程只是立即等待它完成的目的是什么;自由缓冲区;freerecvBuf;???退出后的代码没有意义-当您调用exit时,调用进程将不再存在。是的。OP对malloc的每次调用有两个空闲调用,对socket的每次调用有两个关闭调用。那不行
没错。也许他已经习惯了fork,它创建了复制资源的进程。线程共享它们。回答很好,但我不同意这个说法:当调用fread时,您需要使用rb而不是r。您建议如何处理线程的关闭?我应该在哪里编线程连接或线程退出?@SteveSummit:如果您不使用b标志以二进制模式打开文件流,那么流将以文本模式打开,这允许fread更改它读取的数据,这通常是不可取的。@Tam211:我在我的answer@RemyLebeau我如果文件是文本文件,我会说这些更改正是您想要的。我认为r和rb之间的选择应该基于文件的类型,而不是要进行的I/O调用的选择。