Using Socket in C to Realize Multi-threaded Asynchronous TCP Message Sending

In this article, we will explore how to use socket in C language to implement multi-threaded, asynchronous sending TCP message system. Although the C standard library does not natively support asynchronous and multi-threaded programming, we can use the POSIX thread (pthread) library and socket to achieve the goal.
insert image description here

basic knowledge

TCP (Transmission Control Protocol) is a connection-oriented, reliable, byte stream-based communication protocol.

Socket is a network programming interface that allows applications to send and receive data over the network.

Multithreaded programming is a method of executing multiple tasks concurrently, with each task running in a separate thread.

Asynchronous messaging is a programming model where the sender of a message does not need to wait for the receiver to process the message, it can return immediately and continue with other tasks.

start to realize

First, we need to include the necessary header files.

#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <unistd.h>

Then, we define a function send_messagethat will be called in a new thread to send the message.

void* send_message(void* arg)
{
    
    
    char* message = (char*)arg;
    int sock;
    struct sockaddr_in server;

    // Create socket
    sock = socket(AF_INET , SOCK_STREAM , 0);
    if (sock == -1)
    {
    
    
        perror("Could not create socket");
        return NULL;
    }

    server.sin_addr.s_addr = inet_addr("127.0.0.1");
    server.sin_family = AF_INET;
    server.sin_port = htons(8888);

    // Connect to remote server
    if (connect(sock, (struct sockaddr*)&server, sizeof(server)) < 0)
    {
    
    
        perror("Connect failed");
        return NULL;
    }

    // Send some data
    if (send(sock, message, strlen(message), 0) < 0)
    {
    
    
        perror("Send failed");
        return NULL;
    }

    close(sock);

    return NULL;
}

This send_messagefunction first creates a socket and connects to the remote server. Then, it sends a message, and closes the socket.

Now, we can create multiple threads in the main function, and each thread sends a message.

int main()
{
    
    
    // Array of messages to be sent
    char* messages[] = {
    
    "Hello", "from", "C"};

    // Create a new thread for each message
    pthread_t threads[sizeof(messages)/sizeof(char*)];
    for (int i = 0; i < sizeof(messages)/sizeof(char*); i++)
    {
    
    
       if (pthread_create(&threads[i], NULL, send_message, messages[i]) < 0)
       {
    
    
           perror("Could not create thread");
           return 1;
       }
    }

    // Wait for all threads to finish
    for (int i = 0; i < sizeof(threads)/sizeof(pthread_t); i++)
    {
    
    
        pthread_join(threads[i], NULL);
    }

    return 0;
}

In this code, we create a new thread for each message to be sent and pass send_messagethe function as the thread function. Then, we wait for all threads to complete.

Main function description

1. socket function

The socket function is used to create a socket and return the file descriptor of the socket, which is <sys/socket.h>defined in the header file. Its function prototype is as follows:

int socket(int domain, int type, int protocol);
  • domain: This parameter specifies the protocol family (Protocol Family) used. Common protocol families include AF_INET (IPv4 network protocol), AF_INET6 (IPv6 network protocol) and so on.

  • type: This parameter specifies the service type. Common service types include SOCK_STREAM (provide connection-oriented stable data transmission, that is, TCP protocol), SOCK_DGRAM (provide connectionless unstable data transmission, that is, UDP protocol), etc.

  • protocol: This parameter is usually set to 0, allowing the system to typeautomatically select the appropriate protocol, such as TCP or UDP.

If the socket function succeeds, return a new socket descriptor; otherwise return -1 and set errno to the error number.

2. pthread_create function

The pthread_create function is used to create a new thread and let the new thread execute the specified function. It is <pthread.h>defined in the header file. Its function prototype is as follows:

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
  • thread: This is an output parameter that returns the newly created thread ID.

  • attr: A pointer to a thread attribute structure, used to set the attributes of the new thread. If set to NULL, default properties are used.

  • start_routine: A function pointer pointing to the function to be run by the new thread.

  • arg: A pointer to start_routinethe parameter to be passed to.

If the pthread_create function succeeds, it returns 0; if it fails, it returns a non-zero error code (note that this function does not set errno). The newly created thread start_routinestarts running from the address of the function, and once start_routineit returns, the thread will automatically end.

conclusion

This is a simple example of using sockets in C to implement multi-threaded asynchronous sending of TCP messages. This is a basic example, actual use may require adding error handling and exception handling code. At the same time, because the C language has no built-in asynchronous or multithreading support, this method is not completely asynchronous, but we can simulate asynchronous behavior by using multithreading.

Guess you like

Origin blog.csdn.net/lzyzuixin/article/details/132346553