在本篇文章中,我们会探讨如何在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;
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);
if (connect(sock, (struct sockaddr*)&server, sizeof(server)) < 0)
perror("Connect failed");
return NULL;
if (send(sock, message, strlen(message), 0) < 0)
perror("Send failed");
return NULL;
close(sock);
return NULL;
此send_message
函数首先创建一个socket,并连接到远程服务器。然后,它发送一条消息,并关闭socket。
现在,我们可以在main函数中创建多个线程,每个线程发送一条消息。
int main()
char* messages[] = {"Hello", "from", "C"};
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;
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语言没有内置的异步或多线程支持,所以这种方法并不完全异步,但是我们可以通过使用多线程来模拟异步行为。
两个程序都是基于Select异步模型的,其中服务端还用到了多线程技术,保证了多客户端的连接
都是消息触发和回调的
用多线程就能够保证多客户端的同时连接,要满足更多的客户端连接,要用到线程池模型,有待于更进一步的探讨和研究
QQ:593485230
E-mai:cangzhu@163.com
这是一个套接字模块。使用内置iocp实现异步操作。使用了线程安全的队列操作回调,保证了对应域下的回调操作不需要加锁。async_socket.e。套接字模块。使用复杂,但是灵活,支持各种协议。tcpudp.e。傻瓜封装的TCP和UDP模块。简化操作操作流程。----------------------------------------------------------。v2.0。更新说明(2019-03-03)。async_socket.e 。async_socket_create 返回值与套接字描述符脱钩,失败返回 0,成功 != 0。性能提升 90%(1.x版本是易语言字节集慢导致性能暴降)。async_socket_dll.e 。c代码编写 性能再次提高 17%。tcpudp.e。逻辑无修改,适配新模块代码。@my小黑。Tags:异步套接字源码。
修改 run的实现方式 提升效率
修改 socket_create 创建UDP套接字时,增加默认SIO_UDP_CONNRESET = 0
修复 strand_post 一处bug(这个bug有几率导致崩溃)
不出意外的话这是最终版本了
有bug可以反馈
------------------------------------------------------------------------
内置iocp实现异步操作
封装为套接字模块,支持原始套接字 tcp udp等操作
支持 ipv4ipv6
纯易语言源码