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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/304192.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

labview技术交流-如何判断一个数是否为质数

问题起源 如何判断一个数是否为质数&#xff0c;其实并不难&#xff0c;只要你知道质数的定义&#xff0c;按照它的定义去编写代码就可以了。但是没有思路的人可能就会一直找不到方向&#xff0c;所以我就简单介绍一下。 还有我想吐槽的点&#xff0c;labview本来就是很小众的语…

外包干了15天,技术倒退明显

先说情况&#xff0c;大专毕业&#xff0c;18年通过校招进入湖南某软件公司&#xff0c;干了接近6年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落&#xff01; 而我已经在一个企业干了四年的功能…

uniapp小程序中使用video视频播放卡顿

问题:在使用uniapp小程序的video视频播放,视频已经在播放了,但是进度条没走,还是卡顿的状态(测试ios能正常使用,安卓手机会出现此问题) 在网上找了很多方法,最多的说是用:custom-cache"false",试了并没有效果,看来和我问题不一样,后来用了个简单粗暴的方法,发现是有效…

详解Spring event如何优雅实现系统业务解耦、实现原理及使用注意项

1.概述 在我们平时的项目业务系统开发过程中&#xff0c;一个需求功能的业务逻辑经常出现主线业务和副线业务之分。比如&#xff0c;在当下移动端电商app进行注册账号操作&#xff0c;注册成功之后会发送短信、邮箱、站内信等通知&#xff0c;发放红包活动抵用券&#xff0c;推…

配置VM开机自启动

1. 在此电脑-右键选择“管理”-服务和应用程序-服务中找到VMware Workstation Server服务&#xff08;新版名称也可能是VMware自启动服务&#xff0c;自己找一下&#xff0c;服务属性里有描述信息的&#xff09;&#xff0c;将其启用并选择开机自动启动 新版参考官方文档&…

STC89C52学习笔记(八)

STC89C52学习笔记&#xff08;八&#xff09; 综述&#xff1a;本文讲述了LED点阵屏以及如何进行数据串行输入&#xff0c;并行输出。 一、LED点阵屏 1.介绍 LED点阵屏由多个LED组成&#xff0c;以矩阵形式排列&#xff08;类似于矩阵键盘&#xff09;&#xff0c;像素一般…

数据库的负载均衡,高可用实验

一 高可用负载均衡集群数据库实验 1.实验拓扑图 2.实验准备(同一LAN区段)&#xff08;ntp DNS&#xff09; 客户端&#xff1a;IP&#xff1a;192.168.1.5 下载&#xff1a;MariaDB 负载均衡器&#xff1a;IP&#xff1a;192.168.1.1 下载&#xff1a;keepalived ipvsadm I…

3. DAX 时间函数-- DATE 日期--一生二,二生三,三生万物

在数据分析过程中&#xff0c;经常需要从一个数据推到另外一个数据&#xff0c;日期数据也是如此&#xff0c;需要从一个日期推到另外一个相关的日期&#xff0c;或者从一群日期推到另外一个相关的日期/一群相关的日期。这一期说的就是日期之间彼此推衍的函数&#xff0c;会比之…

OpenHarmony开发技术:【国际化】实例

国际化 如今越来的越多的应用都走向了海外&#xff0c;应用走向海外需要支持不同国家的语言&#xff0c;这就意味着应用资源文件需要支持不同语言环境下的显示。本节就介绍一下设备语言环境变更后&#xff0c;如何让应用支持多语言。 应用支持多语言 ArkUI开发框架对多语言的…

蓝桥杯-单片机基础16——利用定时计数中断进行动态数码管的多窗口显示

综合查阅了网络上目前能找到的所有关于此技能的代码&#xff0c;最终找到了下述方式比较可靠&#xff0c;且可以自定义任意显示的数值。 传统采用延时函数的方式实现动态数码管扫描&#xff0c;在题目变复杂时效果总是会不佳&#xff0c;因此在省赛中有必要尝试采用定时计数器中…

Kafka是什么,以及如何使用SpringBoot对接Kafka

系列文章目录 上手第一关&#xff0c;手把手教你安装kafka与可视化工具kafka-eagle 架构必备能力——kafka的选型对比及应用场景 Kafka存取原理与实现分析&#xff0c;打破面试难关 防止消息丢失与消息重复——Kafka可靠性分析及优化实践 Kafka是什么&#xff0c;以及如何使用…

Vue的学习之旅-part6-循环的集中写法与ES6增强语法

Vue的学习之旅-循环的集中写法与ES6增强语法 vue中的几种循环写法for循环for in 循环 for(let i in data){}for of 循环 for(let item of data){}reduce() 遍历 reduce( function( preValue, item){} , 0 ) ES6增强写法 类似语法糖简写对象简写函数简写 动态组件中使用 <kee…

dnspy逆向和de4dot脱壳

拿到一个软件&#xff0c;使用dnspy查看&#xff0c;发现反汇编后关键部分的函数名和代码有很多乱码&#xff1a; 这样的函数非常多&#xff0c;要想进一步调试和逆向&#xff0c;就只能在dnspy中看反汇编代码了&#xff0c;而无法看到c#代码&#xff0c;当时的整个逆向过程只剩…

windows安装Redis,Mongo,ES并快速基本掌握开发流程

前言 这里只是一些安装后的基础操作&#xff0c;后期会学习更加深入的操作 基础操作 前言RedisRedis启动idea集成Redisjedis技术 Mongodbwindows版Mongodb的安装idea整合Mongodb ES(Elasticsearch)ESwindows下载ES文档操作idea整合ES低级别ES整合高级别ES整合 Redis Redis是…

Java项目:基于Springboot+vue实现的中国陕西民俗前后台管理系统设计与实现(源码+数据库+毕业论文)

一、项目简介 本项目是一套基于Springbootvue实现的中国陕西民俗管理系统设计与实现设 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、界…

git bash用法-批量修改文件名

在win系统上安装git bash可以使用命令行模式操作&#xff0c;比较方便 1.原始文件名 2.代码 for file in *3utr*; do mv "$file" "$(echo "$file" | sed s/3utr/5utr/)"; done3.修改后的文件名

【Web开发】jquery图片放大镜效果制作变焦镜头图片放大

jquery图片放大镜效果制作变焦镜头图片放大实现 整体步骤流程&#xff1a; 1. 前端html实现 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns"…

Android 四大组件启动

service: startService启动过程分析 - Gityuan博客 | 袁辉辉的技术博客 在整个startService过程&#xff0c;从进程角度看服务启动过程 Process A进程&#xff1a;是指调用startService命令所在的进程&#xff0c;也就是启动服务的发起端进程&#xff0c;比如点击桌面App图标…

LeetCode513:找树左下角的值

题目描述 给定一个二叉树的 根节点 root&#xff0c;请找出该二叉树的 最底层 最左边 节点的值。 假设二叉树中至少有一个节点。 代码 层序遍历 class Solution { public:int findBottomLeftValue(TreeNode* root) {if (root nullptr) return 0;queue<TreeNode*> que…

二、计算机网络体系结构参考模型

一、分层结构 &#xff08;一&#xff09;为什么要分层&#xff1a; 发送文件/数据前要完成的工作&#xff1a; 1&#xff09;发起通信的计算机必须讲数据通信通路进行激活 2&#xff09;要告诉网络如何识别目的主机 3&#xff09;发起通信的计算机要查明目的主机是否开机、并且…