在C中使用Socket实现多线程异步TCP消息发送

在本篇文章中,我们会探讨如何在C语言中使用socket来实现多线程,异步发送TCP消息的系统。虽然C标准库并没有原生支持异步和多线程编程,但是我们可以结合使用POSIX线程(pthread)库和socket来达到目的。
在这里插入图片描述

基础知识

TCP (Transmission Control Protocol) 是一种面向连接的、可靠的、基于字节流的通信协议。

Socket 是一种网络编程接口,它允许应用程序在网络上发送和接收数据。

多线程编程 是一个并发执行多个任务的方法,每个任务运行在一个单独的线程中。

异步消息发送 是一种编程模型,消息发送者不需要等待接收者处理消息,它可以立即返回并继续执行其它任务。

开始实现

首先,我们需要包含必要的头文件。

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

然后,我们定义一个函数send_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;
}

send_message函数首先创建一个socket,并连接到远程服务器。然后,它发送一条消息,并关闭socket。

现在,我们可以在main函数中创建多个线程,每个线程发送一条消息。

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;
}

在这段代码中,我们为每个要发送的消息创建了一个新的线程,并传递send_message函数作为线程函数。然后,我们等待所有的线程完成。

主要函数说明

1. socket函数

socket函数是用来创建一个套接字,并返回这个套接字的文件描述符,它在<sys/socket.h>头文件中定义。其函数原型如下:

int socket(int domain, int type, int protocol);
  • domain:此参数指定使用的协议族(Protocol Family)。常见的协议族有AF_INET(IPv4网络协议)、AF_INET6(IPv6网络协议)等。

  • type:此参数指定服务类型。常见的服务类型有SOCK_STREAM(提供面向连接的稳定数据传输,即TCP协议)、SOCK_DGRAM(提供无连接的不稳定数据传输,即UDP协议)等。

  • protocol:此参数通常设置为0,让系统根据type自动选择合适的协议,例如TCP或UDP。

如果socket函数成功,返回一个新的socket描述符;否则返回-1,并设置errno为错误号。

2. pthread_create函数

pthread_create函数用来创建一个新线程,并让这个新线程执行指定的函数。它在<pthread.h>头文件中定义。其函数原型如下:

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
  • thread:这是一个输出参数,用于返回新创建的线程ID。

  • attr:一个指向线程属性结构的指针,用于设置新线程的属性。如果设置为NULL,则使用默认属性。

  • start_routine:一个函数指针,指向新线程要运行的函数。

  • arg:一个指针,指向要传递给start_routine的参数。

如果pthread_create函数成功,返回0;如果失败,则返回一个非0的错误码(注意,这个函数不会设置errno)。新创建的线程从start_routine函数的地址开始运行,一旦start_routine返回,那么这个线程就会自动结束。

结束语

这就是在C中使用socket实现多线程异步发送TCP消息的简单示例。这是一个基础的示例,实际使用时可能需要添加错误处理和异常处理代码。同时,因为C语言没有内置的异步或多线程支持,所以这种方法并不完全异步,但是我们可以通过使用多线程来模拟异步行为。

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
可以通过以下步骤实现: 1. 创建一个服务端Socket对象,绑定IP地址和端口号,并开始监听连接请求。 ```csharp Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8888); serverSocket.Bind(ipEndPoint); serverSocket.Listen(10); ``` 2. 使用异步方法Accept()等待客户端连接请求,并在客户端连接成功后,创建一个新的线程来处理客户端的消息。 ```csharp while (true) { Socket clientSocket = await serverSocket.AcceptAsync(); Thread thread = new Thread(() => HandleClient(clientSocket)); thread.Start(); } ``` 3. 在处理客户端消息的线程使用异步方法Receive()接收客户端发送消息,并使用异步方法Send()向客户端发送消息。 ```csharp private async void HandleClient(Socket clientSocket) { while (true) { byte[] buffer = new byte[1024]; int len = await clientSocket.ReceiveAsync(new ArraySegment<byte>(buffer), SocketFlags.None); string message = Encoding.UTF8.GetString(buffer, 0, len); Console.WriteLine($"Receive from {clientSocket.RemoteEndPoint}: {message}"); byte[] sendBuffer = Encoding.UTF8.GetBytes("Hello from server!"); await clientSocket.SendAsync(new ArraySegment<byte>(sendBuffer), SocketFlags.None); } } ``` 通过以上步骤,就可以实现多个客户端的相互连接,并可以发送消息。需要注意的是,需要在客户端也使用异步方法来接收和发送消息
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

醉心编码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值