简体   繁体   English

C中的多线程TCP服务器

[英]Multi Threaded TCP Server in C

int sock, connected, bytes_received, true = 1;
struct sockaddr_in server_addr, client_addr;
int sin_size;

if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    perror("Socket");
    exit(1);
}

if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &true, sizeof (int)) == -1) {
    perror("Setsockopt");
    exit(1);
}

server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(atoi(argv[1]));
server_addr.sin_addr.s_addr = INADDR_ANY;
bzero(&(server_addr.sin_zero), 8);

if (bind(sock, (struct sockaddr *) &server_addr, sizeof (struct sockaddr))
        == -1) {
    perror("Unable to bind");
    exit(1);
}

if (listen(sock, 5) == -1) {
    perror("Listen");
    exit(1);
}

printf("\nTCPServer Waiting for client on port 5003");
fflush(stdout); 

while (1) 
{
    pthread_t *child = (pthread_t *)malloc( sizeof(pthread_t) );

    sin_size = sizeof (struct sockaddr_in);
    connected = accept(sock, (struct sockaddr *) &client_addr, &sin_size);
    printf("\n I got a connection from (%s , %d)\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));

    pthread_create(child, NULL, interpretMessage, NULL);
    free(child);
}

My TCP server listens on port 5003. When a connection is made, I want to spawn a thread and run the function interpretMessage. 我的TCP服务器侦听端口5003.当建立连接时,我想生成一个线程并运行函数interpretMessage。 I have a few questions about this... 我有几个问题......

1) Am I doing calling malloc and free in the correct places? 1)我是否正在调用malloc并在正确的位置免费?

2) After pthread_create is called, does my code immediately jump to "free(child);" 2)调用pthread_create后,我的代码会立即跳转到“free(child);” and then back to the beginning of the while loop? 然后回到while循环的开头?

3) What happens if 5 people connect at the same exact time (how does the code run to spawn 5 threads?) 3)如果5个人在同一时间连接会发生什么(代码如何运行以产生5个线程?)

Your code correctly does use malloc and free , but the way that you're doing so makes the implementation more complicated than is necessary. 你的代码正确地使用了mallocfree ,但是你这样做的方式使得实现比必要的更复杂。 The pthread_create function works by writing the ID of the new thread to the memory pointed at by its first parameter. pthread_create函数的工作原理是将新线程的ID写入其第一个参数指向的内存中。 In your case, you've dynamically allocated this buffer and then immediately freed it. 在您的情况下,您已动态分配此缓冲区,然后立即释放它。 Consequently, the memory is scoped to one iteration of the while loop. 因此,存储器的范围限定为while循环的一次迭代。 If this is what you want, you're probably better off just making the pthread_t stack-allocated and passing a pointer to it into pthread_create : 如果这是你想要的,你可能最好只是让pthread_t堆栈分配并将指针传递给pthread_create

while (1) 
{
    pthread_t child;

    /* ... */

    pthread_create(&child, NULL, interpretMessage, NULL);
}

Now that child is locally-scoped to the loop, the memory management will be handled automatically without any need to call malloc or free . 现在, child节点本地作用于循环,内存管理将自动处理,无需调用mallocfree

As for your second question about whether the control continues to free (child) and then back up to the top of the loop after the call to pthread_create , yes, this is correct. 关于控件是否继续free (child)然后在调用pthread_create后返回到循环顶部的第二个问题,是的,这是正确的。 A second thread will be created running interpretMessage , so there may be some delay if the original process gets delayed, but control does resume from this point. 将创建运行interpretMessage第二个线程,因此如果原始进程被延迟可能会有一些延迟,但控制确实会从此点恢复。

For your last question, if five people all connect at exactly the same time, then on the next five times you call accept the function will provide a single socket for the next incoming connection. 对于你的上一个问题,如果五个人都在同一时间连接,那么在接下来的五次你调用accept该函数将为下一个传入连接提供一个套接字。 That is, the OS will automatically queue up the incoming connections into some order, and on each iteration of the loop your code will notice that there's a connection, get a socket for it, then spawn off a thread to process the message. 也就是说,操作系统会自动将传入的连接排队到某个顺序,并且在循环的每次迭代中,您的代码会注意到有连接,为它获取套接字,然后产生一个线程来处理消息。

One thing I noticed in your code - when you're spawning off a thread to call interpretMessage , you didn't provide any arguments to the function, and so each thread will operate without any context for how it was created. 我在你的代码中注意到的一件事 - 当你产生一个调用interpretMessage的线程时,你没有为函数提供任何参数,因此每个线程都将在没有任何创建它的上下文的情况下运行。 Was this intentional? 这是故意的吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM