021——搭建TCP网络通信环境(c服务器python客户端)

2024-04-11 02:44

本文主要是介绍021——搭建TCP网络通信环境(c服务器python客户端),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

前言

服务器程序

服务器程序验证过程

客户端程序


前言

        驱动开发暂时告一段落了。后面在研究一下OLED和GPS的驱动开发,并且优化前面已经移植过来的这些驱动,我的理念是在封装个逻辑处理层来处理这些驱动程序。server直接操作逻辑处理层的程序。

        这次服务器的开发也不会一步到位,先做最简单的然后在逐渐迭代。

服务器程序

/*  * 文件名: server.c  * 作者: 辛天宇  * 更新时间: 2024-04-10  * 软件版本号: 0.0.0  */
/**************************************************************
***************************INCLUDE*****************************
**************************************************************/
#include "net.h"
/**************************************************************
****************************LOCAL******************************
**************************************************************/
void cli_data_handle (void *arg);
int main()
{int fd = -1;struct sockaddr_in sin;//创建socket fd*if((fd = socket(AF_INET,SOCK_STREAM, 0)) < 0){perror("socket");//return -1;exit(1);}/*优化4: 允许绑定地址快速重用 */int b_reuse = 1;setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &b_reuse, sizeof (int));//绑定//填充struct socketddr_in结构体变量bzero(&sin,sizeof(sin));//把sin全填充0sin.sin_family = AF_INET;//地址族网际网区域sin.sin_port = htons(SERV_PORT); //网络字节端口号//优化使server可以绑定在任意IP上
#if 1sin.sin_addr.s_addr = htonl(INADDR_ANY);//INADDY_ANY = -1
#elseif( inet_pton(AF_INET,SERV_IP_ADDR,(void *)&sin.sin_addr) != 1){perror("inet_pton");exit(1);		}
#endif//绑定if(bind(fd, (struct sockaddr *)&sin, sizeof(sin)) < 0) {perror("bind");exit(1);}//调用listen()把主动套接字变成被动套接字if(listen(fd,BACKLOG) < 0 ){perror("listen");exit(1);}printf("Server starting...OK!\n");int newfd = -1;//阻塞等待客户端连接
#if 0newfd = accept(fd, NULL, NULL);if(newfd < 0){perror("accept");exit(1);}
#else
//通过程序获取刚建立连接的socket客户端的ip地址和端口号pthread_t tid;struct sockaddr_in cin;socklen_t addrlen = sizeof (cin);while (1) {if ((newfd = accept (fd, (struct sockaddr *) &cin, &addrlen)) < 0) {perror ("accept");exit (1);}char ipv4_addr[16];if (!inet_ntop (AF_INET, (void *) &cin.sin_addr, ipv4_addr, sizeof (cin))) {perror ("inet_ntop");exit (1);}printf ("Clinet(%s:%d) is connected!\n", ipv4_addr, htons (cin.sin_port));pthread_create (&tid, NULL, (void *) cli_data_handle, (void *) &newfd);}close (fd);return 0;
}
#endif
void cli_data_handle (void *arg)
{int newfd = *(int *) arg;printf ("handler thread: newfd =%d\n", newfd);//..和newfd进行数据读写int ret = -1;char buf[BUFSIZ];while (1) {bzero (buf, BUFSIZ);do {ret = read (newfd, buf, BUFSIZ - 1);} while (ret < 0 && EINTR == errno);if (ret < 0) {perror ("read");exit (1);}if (!ret) {				//对方已经关闭break;}printf ("Receive data: %s\n", buf);if (!strncasecmp (buf, QUIT_STR, strlen (QUIT_STR))) {	//用户输入了quit字符printf ("Client(fd=%d) is exiting!\n", newfd);break;}}close (newfd);}

这是以前学网络编程的时候写的拿过来改一改

稍微改一下

/*
*author   : xintianyu
*function : main
*data     : 2024-4-10
-----------------------
*author : ???
*return : ???
*data   : ???
*/
int main(int argc, char *argv[])
{if(ERROR == usage(argc, argv))return 0;tcp_server(argc, argv);return 0;
}
/*
*author : xintianyu
*return : err num
*data   : 2024-4-10
-----------------------
*author : ???
*return : ???
*data   : ???
*/
int usage(int argc, char *argv[])
{ if (argc != 3){  printf("Usage: %s <ip_address> <port>\n", argv[0]);  return ERROR;  }else{return NOERROR;}
}
/*
*author : xintianyu
*return : err num
*data   : 2024-4-10
-----------------------
*author : ???
*return : ???
*data   : ???
*/
int tcp_server(int argc, char *argv[]) 
{int server_fd, client_fd;  struct sockaddr_in server_addr, client_addr;  socklen_t client_len = sizeof(client_addr);  char buffer[BUFFER_SIZE];  char *ip_address = argv[1];  int port = atoi(argv[2]);  // 创建TCP套接字  if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {  perror("socket creation failed");  exit(EXIT_FAILURE);  }  // 设置服务器地址信息  memset(&server_addr, 0, sizeof(server_addr));  server_addr.sin_family = AF_INET;  server_addr.sin_addr.s_addr = inet_addr(ip_address);  server_addr.sin_port = htons(port);  // 绑定套接字到服务器地址  if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {  perror("bind failed");  exit(EXIT_FAILURE);  }  // 监听套接字  if (listen(server_fd, 5) < 0) {  perror("listen failed");  exit(EXIT_FAILURE);  }  printf("Server listening on %s:%d...\n", ip_address, port);  while (1) {  // 接受客户端连接  if ((client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &client_len)) < 0) {  perror("accept failed");  continue;  }  // 打印客户端信息  char client_ip[INET_ADDRSTRLEN];  inet_ntop(AF_INET, &client_addr.sin_addr, client_ip, INET_ADDRSTRLEN);  printf("Client connected from %s:%d\n", client_ip, ntohs(client_addr.sin_port));  // 接收客户端消息  memset(buffer, 0, BUFFER_SIZE);  ssize_t bytes_read = recv(client_fd, buffer, BUFFER_SIZE - 1, 0);  if (bytes_read < 0) {  perror("recv failed");  close(client_fd);  continue;  }  // 确保消息以换行符结尾,并打印接收到的消息  if (bytes_read > 0 && buffer[bytes_read - 1] != '\n') {  buffer[bytes_read] = '\n';  buffer[bytes_read + 1] = '\0';  }  printf("Received message: %s", buffer);  // 回复客户端消息  strcpy(buffer, "Hello, client!\n");  if (send(client_fd, buffer, strlen(buffer), 0) < 0) {  perror("send failed");  }  close(client_fd);  }close(server_fd);return NOERROR;  
}

写的比较简单因为没有业务逻辑暂时只是验证通信问题。

服务器程序验证过程

编译命令

这是我们现在的目录结构

客户端程序

import socketserver_ip   = '192.168.5.110'
server_port = 8888 # 设置服务器地址和端口  
server_address = (server_ip, server_port)
# 创建一个socket对象
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 连接到服务器  
client_socket.connect(server_address)  
try:  # 发送数据  message = 'Hello, server!'.encode()  print(f'Sending {message}')  client_socket.sendall(message)  # 接收数据  amount_received = 0  amount_expected = len(message)  while amount_received < amount_expected:  data = client_socket.recv(16)  amount_received += len(data)  print(f'Received {data}')  finally:  # 关闭连接  print('Closing socket')  client_socket.close()

一下就没了我优化一下让他可以一直通信

import socket  server_ip   = '192.168.5.110'
server_port = 8888 # 设置服务器地址和端口  
server_address = (server_ip, server_port)# 创建一个socket对象  
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # 连接到服务器  
try:  client_socket.connect(server_address)  print(f'Connected to {server_address}')  # 接收用户输入并发送给服务器  while True:  try:  user_input = input('Enter command (or "exit" to quit): ')  if user_input.lower() == 'exit':  break  client_socket.sendall(user_input.encode())  # 接收服务器的响应  data = client_socket.recv(1024)  print(f'Received: {data.decode()}')  except KeyboardInterrupt:  print('\nKeyboardInterrupt received, exiting...')  break  except ConnectionResetError:  print('\nConnection reset by server, exiting...')  break  except Exception as e:  print(f'An error occurred: {e}, trying to reconnect...')  client_socket.close()  # Close the socket if there's an error  client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # Create a new one  client_socket.connect(server_address)  # Reconnect to the server  finally:  # 关闭连接  print('Closing socket')  client_socket.close()

有问题哇,只能发过去第一条

一顿debug发现是服务器的问题,现在算是通讯正常了。

服务器最新程序

int tcp_server(int argc, char *argv[]) 
{int server_fd, client_fd;  struct sockaddr_in server_addr, client_addr;  socklen_t client_len = sizeof(client_addr);  char buffer[BUFFER_SIZE];  char *ip_address = argv[1];  int port = atoi(argv[2]);  // 创建TCP套接字  if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {  perror("socket creation failed");  exit(EXIT_FAILURE);  }  // 设置服务器地址信息  memset(&server_addr, 0, sizeof(server_addr));  server_addr.sin_family = AF_INET;  server_addr.sin_addr.s_addr = inet_addr(ip_address);  server_addr.sin_port = htons(port);  // 绑定套接字到服务器地址  if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {  perror("bind failed");  exit(EXIT_FAILURE);  }  // 监听套接字  if (listen(server_fd, 5) < 0) {  perror("listen failed");  exit(EXIT_FAILURE);  }  printf("Server listening on %s:%d...\n", ip_address, port);  // 接受客户端连接  if ((client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &client_len)) < 0) {  perror("accept failed");  }while (1) {// 打印客户端信息  char client_ip[INET_ADDRSTRLEN];  inet_ntop(AF_INET, &client_addr.sin_addr, client_ip, INET_ADDRSTRLEN);  printf("Client connected from %s:%d\n", client_ip, ntohs(client_addr.sin_port));  // 接收客户端消息  memset(buffer, 0, BUFFER_SIZE);  ssize_t bytes_read = recv(client_fd, buffer, BUFFER_SIZE - 1, 0);  if (bytes_read < 0) {  perror("recv failed");  close(client_fd);  continue;  }  // 确保消息以换行符结尾,并打印接收到的消息  if (bytes_read > 0 && buffer[bytes_read - 1] != '\n') {  buffer[bytes_read] = '\n';  buffer[bytes_read + 1] = '\0';  }  printf("Received message: %s", buffer);  // 回复客户端消息  strcpy(buffer, "Hello, client!\n");  if (send(client_fd, buffer, strlen(buffer), 0) < 0) {  perror("send failed");  }}close(client_fd); close(server_fd);return NOERROR;  
}

这篇关于021——搭建TCP网络通信环境(c服务器python客户端)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/892876

相关文章

Python的Darts库实现时间序列预测

《Python的Darts库实现时间序列预测》Darts一个集统计、机器学习与深度学习模型于一体的Python时间序列预测库,本文主要介绍了Python的Darts库实现时间序列预测,感兴趣的可以了解... 目录目录一、什么是 Darts?二、安装与基本配置安装 Darts导入基础模块三、时间序列数据结构与

Python正则表达式匹配和替换的操作指南

《Python正则表达式匹配和替换的操作指南》正则表达式是处理文本的强大工具,Python通过re模块提供了完整的正则表达式功能,本文将通过代码示例详细介绍Python中的正则匹配和替换操作,需要的朋... 目录基础语法导入re模块基本元字符常用匹配方法1. re.match() - 从字符串开头匹配2.

Python使用FastAPI实现大文件分片上传与断点续传功能

《Python使用FastAPI实现大文件分片上传与断点续传功能》大文件直传常遇到超时、网络抖动失败、失败后只能重传的问题,分片上传+断点续传可以把大文件拆成若干小块逐个上传,并在中断后从已完成分片继... 目录一、接口设计二、服务端实现(FastAPI)2.1 运行环境2.2 目录结构建议2.3 serv

通过Docker容器部署Python环境的全流程

《通过Docker容器部署Python环境的全流程》在现代化开发流程中,Docker因其轻量化、环境隔离和跨平台一致性的特性,已成为部署Python应用的标准工具,本文将详细演示如何通过Docker容... 目录引言一、docker与python的协同优势二、核心步骤详解三、进阶配置技巧四、生产环境最佳实践

Python一次性将指定版本所有包上传PyPI镜像解决方案

《Python一次性将指定版本所有包上传PyPI镜像解决方案》本文主要介绍了一个安全、完整、可离线部署的解决方案,用于一次性准备指定Python版本的所有包,然后导出到内网环境,感兴趣的小伙伴可以跟随... 目录为什么需要这个方案完整解决方案1. 项目目录结构2. 创建智能下载脚本3. 创建包清单生成脚本4

Python实现Excel批量样式修改器(附完整代码)

《Python实现Excel批量样式修改器(附完整代码)》这篇文章主要为大家详细介绍了如何使用Python实现一个Excel批量样式修改器,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录前言功能特性核心功能界面特性系统要求安装说明使用指南基本操作流程高级功能技术实现核心技术栈关键函

python获取指定名字的程序的文件路径的两种方法

《python获取指定名字的程序的文件路径的两种方法》本文主要介绍了python获取指定名字的程序的文件路径的两种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要... 最近在做项目,需要用到给定一个程序名字就可以自动获取到这个程序在Windows系统下的绝对路径,以下

使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解

《使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解》本文详细介绍了如何使用Python通过ncmdump工具批量将.ncm音频转换为.mp3的步骤,包括安装、配置ffmpeg环... 目录1. 前言2. 安装 ncmdump3. 实现 .ncm 转 .mp34. 执行过程5. 执行结

Python实现批量CSV转Excel的高性能处理方案

《Python实现批量CSV转Excel的高性能处理方案》在日常办公中,我们经常需要将CSV格式的数据转换为Excel文件,本文将介绍一个基于Python的高性能解决方案,感兴趣的小伙伴可以跟随小编一... 目录一、场景需求二、技术方案三、核心代码四、批量处理方案五、性能优化六、使用示例完整代码七、小结一、

Python中 try / except / else / finally 异常处理方法详解

《Python中try/except/else/finally异常处理方法详解》:本文主要介绍Python中try/except/else/finally异常处理方法的相关资料,涵... 目录1. 基本结构2. 各部分的作用tryexceptelsefinally3. 执行流程总结4. 常见用法(1)多个e