Table of contents
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.
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_message
that 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_message
function 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_message
the 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 totype
automatically 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 tostart_routine
the 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_routine
starts running from the address of the function, and once start_routine
it 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.