首页 > 编程语言 >C语言网络编程(一对多通讯)

C语言网络编程(一对多通讯)

时间:2024-07-16 16:08:42浏览次数:9  
标签:通讯 addr read 编程 C语言 fd readBuf include 客户端

使用C语言实现一个服务器对多个客户端

主要技术除了网络编程几个函数的使用外,还用到了线程,实现方式是一个客户端对应一个新的线程

Server:

#include <pthread.h> // 包含线程库的头文件 #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <unistd.h>
void* handle_client(void* arg) { int client_fd = *(int*)arg; // 从参数中获取客户端套接字文件描述符 char readBuf[128]; char *writeBuf = "I get you!";
while (1) { sleep(2);//很重要,防止服务器一直连接同一个客户端 // 循环读取客户端发送的每条消息 memset(readBuf, 0, sizeof(readBuf)); int n_read = read(client_fd, readBuf, sizeof(readBuf)); if (n_read > 0) { // 正常接收到消息 printf("get message from client: %s\n", readBuf); } else if (n_read == 0) { // 客户端关闭连接 printf("Client disconnected.\n"); break; } else { // 读取失败 perror("read"); break; }
// 发送消息回客户端 if (write(client_fd, writeBuf, sizeof(writeBuf)) == -1) { perror("write"); break; } }
close(client_fd); // 关闭客户端套接字 pthread_exit(NULL); // 退出线程 }
int main() { int s_fd, c_fd; struct sockaddr_in s_addr, c_addr; socklen_t len; char readBuf[128]; char *writeBuf = "I get you!"; // 1. 创建socket网络套接字 s_fd = socket(AF_INET, SOCK_STREAM, 0); if (s_fd == -1) { perror("socket"); exit(-1); }
// 2. 绑定本地IP地址和端口号到socket网络套接字上 memset(&s_addr, 0, sizeof(struct sockaddr_in)); s_addr.sin_family = AF_INET; s_addr.sin_port = htons(8421); inet_aton("192.168.190.141", &s_addr.sin_addr); if (bind(s_fd, (struct sockaddr*)&s_addr, sizeof(struct sockaddr_in)) == -1) { perror("bind"); exit(-1); }
// 3. 将socket套接字变为监听套接字,准备接受客户端的连接 if (listen(s_fd, 10) == -1) { perror("listen"); exit(-1); }
// 4. 服务器阻塞等待客户端的连接 len = sizeof(struct sockaddr_in); // 服务器主循环 while (1) { // 4. 服务器阻塞等待客户端的连接 len = sizeof(struct sockaddr_in); c_fd = accept(s_fd, (struct sockaddr*)&c_addr, &len); if (c_fd == -1) { perror("accept"); exit(-1); } printf("Success Connected\n"); printf("get connect :%s\n", inet_ntoa(c_addr.sin_addr));

  // 创建新线程处理客户端连接 pthread_t thread_id; if (pthread_create(&thread_id, NULL, handle_client, &c_fd) != 0) { perror("pthread_create"); close(c_fd); // 如果线程创建失败,关闭客户端套接字 exit(-1); } // 销毁线程,这里不销毁,让线程自然结束 pthread_detach(thread_id); }
close(s_fd); // 关闭服务器套接字 return 0; }

Client:

#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <unistd.h>
int main() { int c_fd; struct sockaddr_in s_addr; char msg[128], readBuf[128];
// 1. 创建socket网络套接字 c_fd = socket(AF_INET, SOCK_STREAM, 0); if (c_fd == -1) { perror("socket"); exit(-1); }
// 2. 连接服务端 memset(&s_addr, 0, sizeof(struct sockaddr_in)); s_addr.sin_family = AF_INET; inet_aton("192.168.190.141", &s_addr.sin_addr); s_addr.sin_port = htons(8421);
if (connect(c_fd, (struct sockaddr*)&s_addr, sizeof(struct sockaddr_in)) == -1) { perror("connect"); exit(-1); } printf("Connected to server at %s\n", inet_ntoa(s_addr.sin_addr));
// 3. 发送信息到服务端 while (scanf("%127s", msg) == 1) { // 使用%127s防止缓冲区溢出 if (write(c_fd, msg, strlen(msg)) == -1) { perror("write"); break; }
// 4. 读取服务端发来的消息 int n_read = read(c_fd, readBuf, sizeof(readBuf)); if (n_read > 0) { readBuf[n_read] = '\0'; // 确保字符串以null字符结尾 printf("Received message: %s\n", readBuf); } else if (n_read == -1) { perror("read"); break; } else if (n_read == 0) { printf("Server closed the connection.\n"); break; } }
close(c_fd); return 0; }

标签:通讯,addr,read,编程,C语言,fd,readBuf,include,客户端
From: https://www.cnblogs.com/trc258/p/18305460

相关文章

  • Java中的网络编程与TCP/IP协议详解
    Java中的网络编程与TCP/IP协议详解大家好,我是微赚淘客系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!在现代软件开发中,理解和掌握网络编程以及TCP/IP协议是构建高性能网络应用的关键。本文将深入讨论Java中的网络编程技术和TCP/IP协议的工作原理与应用。一、网络编程基础......
  • 开发必备,开源免费的 AI 编程助手
    AI大模型的火热,让开发圈近来如虎添翼,各种各样基于AI技术的开发者工具和新范式不断涌现,尤其是Github和OpenAI共同推出的CopilotX,更是一骑绝尘。本文推荐一些开源or免费的AI编程工具,不妨试着用起来。CodeGeeX有人称CodeGeeX是国产之光,被认为是GitHubCopilot......
  • bluz glib编程 --- 代码片段参考
    获取远端蓝牙的所有属性result=g_dbus_connection_call_sync(conn,"org.bluez",/org/bluez/hci0/dev_A4_C1_38_10_09_2C,"org.freedesktop.DBus.Properties","GetAll",g_variant_new("......
  • bluz glib编程 --- GVariant Format Strings 介绍
    GVariantFormatStrings类型字符串实例分析(sa{sv}as)外层是元组类型,内含三个成员,分别是字符串s字典类型数组a{sv},字符串作为key,variant作为value字符串类型数组as(i@ii)外层是元组类型,内含三个成员,分别是gint类型数字类型ivariant类型@i,对应数字......
  • 3、计划工具 - 编程实战工具系列文章
          计划工具       上次介绍了需求工具。根据项目管理中的内容,五大过程组(启动、计划、执行、监控、收尾),以及软件工程里的内容,需求之后就是计划,所以这次介绍的是计划工具。      对于项目管理中的计划,主要是用Project来进行对需求分解,然后形成WBS内容,......
  • 嵌入式C语言指针面试题大全(持续更新)
    什么是指针?指针在C语言中的作用是什么?在C语言中,指针是一种变量类型,它存储的是其他变量或数据结构的内存地址,而不是实际的数据值。指针允许程序员直接操作和管理内存,这是C语言的一个重要特性,也是它能够高效地处理资源和进行底层编程的原因之一。指针在C语言中有多种作用,包括......
  • 在JavaScript中,如何实现异步编程?
    在JavaScript中,如何实现异步编程?请列举几种常见的方法(如Promise、async/await)。在JavaScript中,异步编程是处理长时间运行的任务(如网络请求、文件读写、大量计算等)的关键。JavaScript是单线程的,但通过使用异步编程模式,我们可以编写出既不会阻塞主线程执行又能处理耗时任务的......
  • C语言 ——— 浮点数类型 在 内存中 的 存储模式
    浮点数存储规则根据国际标准IEEE754(电气和电子工程协会)规定:任意一个浮点数F的二进制都可以表示成以下形式:科学计数法(-1)^S*M*2^E解析科学计数法: 1.解析:(-1)^S(-1)^S 表示的是浮点数F的符号位当S=0时,原式=(-1)^0= 1,此时的 1就表示浮点数F为......
  • 墨烯的C语言技术栈-C语言基础-012
    数组要存储1-100的数字,怎么存储?C语言中给数组的定义:一组相同类型元素的集合数组定义intarr[10]={1,2,3,4,5,6,7,8,9,10};//定义一个整型数组,最多放10个元素intmain(){ //0-9都是整数 intarr[10]={10,11,12,13,14,15,16,17,18,19};//arr是数组名 [......
  • 【C语言】位操作符详解 - 《开心消消乐》
    目录1.介绍2.位操作符列表3.按位操作符详解3.1按位与(&)示例输出3.2按位或(|)示例输出3.3按位异或(^)示例输出3.4按位取反(~)示例输出按位取反操作符(~)示例输出按位取反操作符详细解释3.5左移(<<)示例输出3.6右移(>>)示例输出4.应用实例4.1使用位掩码示例输出4.2......