无法弄清楚为什么我的TCP服务器代码会喷出分段错误

我制作了一个可以与多个客户端一起使用的 TCP线程服务器

  • 服务器将数据从txt文件发送到不同的客户端
  • 对数据求和,然后将总和发送回服务器
  • 接收到的总和加起来。

在总计超过一定数量(约segmentation fault)之后,我在服务器上得到50,000。我不确定是什么原因造成的。

这是我的代码:

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

#define MAX_LEN  1024

// A thread needs a piece of code called thread function to run
// It has a peculiar prototype -- read the topic of "function pointer"
// in a C book.
void *thread_main(void *arg);

// See the above prototype -- the thread main code needs an argument
// of type "void *" -- that is a wildcard pointer type.
// We will pass the following structure using the wildcard pointer.
struct thread_args {
    int new_sock_for_client;
};
static int numLines = 0;
static int totalLines=0;
static int counter = 0;
static float total = 0;
static char t[12] = {0x0};
static _Bool quit = 0;

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

    int sock,newsock;
    struct sockaddr_in server_addr;
    struct sockaddr_in client_addr;
    socklen_t client_addrlen; // client address length (in and out)
    int err_code;
    //---------

    int counter;
    char const *const fileName = "output.txt"; /* should check that argc > 1 */
    FILE *file = fopen(fileName,"r"); /* should check the result */
    char line[256];
    int count = 0;

    while (fgets(line,sizeof(line),file)) {
        numLines++;

    }
    totalLines = numLines;
    //printf("Hello");
    fclose(file);


    //---------
    if (argc < 2) {
        fprintf(stderr,"Error,no port provided.\n");
        exit(0);
    }

    // create socket
    sock = socket(AF_INET,SOCK_STREAM,0);
    if (sock < 0) {
        perror("socket");
        exit(1);
    }

    // build local internet addr/port
    memset(&server_addr,sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = INADDR_ANY;
    server_addr.sin_port = htons(atoi(argv[1]));

    // bind the socket to local internet addr/port
    err_code = bind(sock,(struct sockaddr *) &server_addr,sizeof(server_addr));
    if (err_code < 0) {
        perror("bind");
        exit(2);
    }

    // put server socket in listening state
    err_code = listen(sock,5);
    if (err_code < 0) {
        perror("listen");
        exit(3);
    }

    while (1) {
        // accept new connection (returns new socket)
        client_addrlen = sizeof(client_addr);   // must set (used as input)
        newsock = accept(sock,(struct sockaddr *) &client_addr,&client_addrlen);
        // above call also sets the client_addr and client_addrlen
        // so that we know which client is connected to the server
        if (newsock < 0) {
            perror("accept");
            exit(4);
        }

        // allocate memory for the thread argument
        struct thread_args *targs = malloc(sizeof(struct thread_args));
        if (NULL == targs) {
            perror("malloc");
            exit(7);
        }
        targs->new_sock_for_client = newsock;

        // now we are ready to create a new thread and pass it with the argument
        pthread_t thread_id;
        int code = pthread_create(&thread_id,NULL,thread_main,targs);
        if (code != 0) {
            perror("pthread_create");
            exit(8);
        }

        // At this point,the main thread loops back to accept new connections
        // while the new thread handles the client by running the thread function.

    }
    // NOT reachable

    // close passive socket
    close(sock);

    return 0;
}

void *thread_main(void *arg) {   //printf("%d",numLines);
    char line[256];
    int num_bytes;
    char buf[MAX_LEN];
    unsigned char msglen;

    // detach the current thread from others so that its
    pthread_detach(pthread_self());

    // extract the client socket from the argument
    // the orginal 'newsock' in the main is not visiable here
    int newsock = ((struct thread_args *) arg)->new_sock_for_client;
    free(arg);

    while (1) {
        char const *const fileName = "output.txt"; /* should check that argc > 1 */
        FILE *file = fopen(fileName,"r"); /* should check the result */
        //printf("repeat\n");
// receive data from new socket
        recv(newsock,&msglen,1,0);   // receive the length marker
        unsigned total_bytes_received = 0;
        while (total_bytes_received < msglen) {
            num_bytes = recv(newsock,buf,MAX_LEN,0);
            if (num_bytes < 0) {
                perror("recv");
                exit(5);
            }
            total_bytes_received += num_bytes;
        }
        write(1,"Message from a client: ",23);
        write(1,total_bytes_received);
        printf("\n");
//printf("message received\n");

        //------------start
        if (numLines == 0) {
            break;
        }
        int tempint = counter + 100;
        if (counter != 0) {
            if (numLines > 100) {
                int temp = counter;
                for (int i = 0; i < temp; i++) {
                    fgets(line,file);
                }
                for (int i = counter; i < tempint; i++) {
                    fgets(line,file);

                    char *ack_msg = line;
                    msglen = strlen(ack_msg);
                    send(newsock,0);                   // Send marker
                    num_bytes = send(newsock,ack_msg,msglen,0);  // send ack message
                    if (num_bytes < 0) {
                        perror("sendto");
                        exit(6);
                    }
                    counter++;
                    numLines--;
                }//end forloop
            }//else linesLeft if
            else if (numLines < 100) {
                int temp = counter;
                for (int i = 0; i < temp; i++) {
                    fgets(line,0);  // send ack message
                    if (num_bytes < 0) {
                        perror("sendto");
                        exit(6);
                    }
                    counter++;
                    numLines--;
                    if (counter == totalLines)
                        break;
                }//end forloop
            }//end else if linesLeft

        }//end if counter!=0
        else {
            for (int i = counter; i < tempint; i++) {
                fgets(line,file);

                char *ack_msg = line;
                msglen = strlen(ack_msg);
                send(newsock,0);                   // Send marker
                num_bytes = send(newsock,0);  // send ack message
                if (num_bytes < 0) {
                    perror("sendto");
                    exit(6);
                }
                counter++;
                numLines--;
            }//end forloop

        }//end else


//send "send your total"
        char *ack_msg = "Send your total";
        msglen = strlen(ack_msg);
        send(newsock,0);                   // Send marker
        num_bytes = send(newsock,0);  // send ack message
        if (num_bytes < 0) {
            perror("sendto");
            exit(6);
        }


// receive total from clients
        recv(newsock,0);   // receive the length marker
        total_bytes_received = 0;
        while (total_bytes_received < msglen) {
            num_bytes = recv(newsock,0);
            if (num_bytes < 0) {
                perror("recv");
                exit(5);
            }
            total_bytes_received += num_bytes;
        }


        float temp = atof(buf);
        total += temp;
        write(1,"Sum received from client: ",25);
        sprintf(t,"%f",temp);
        write(1,&t,sizeof(t));
        printf("\n");
        write(1,"Current total: ",14);
        sprintf(t,total);
        write(1,sizeof(t));
        printf("\n\n");

//----------end

    }
//end while-loop

    printf("No more work available. sock closed\n");
    close(newsock);
    write(1,"Final total: ",14);
    sprintf(t,total);
    write(1,sizeof(t));
    printf("\n\n");
    exit(0);

    return NULL;
}
danny8392 回答:无法弄清楚为什么我的TCP服务器代码会喷出分段错误

暂时没有好的解决方案,如果你有好的解决方案,请发邮件至:iooj@foxmail.com
本文链接:https://www.f2er.com/2965488.html

大家都在问