TCP网络编程(三)—— 客户端的编写/服务器端和客户端的通信
上篇文章我们学习了TCP的服务器端模式的编写,这篇文章我们将开始编写客户端的代码,完成服务器端和客户端的通信。完整代码和演示在文章的后面。

和服务器端不同,在客户端我们只需要服务器端的套接字和服务器端的地址和端口,用于向服务器发送连接请求。
这里定义了客户端套接字,服务器端的地址和端口,和上篇文章服务器端的编写一样,详细原理请见上篇文章。
代码生成创建了客户端的套接字,把服务器端的地址和端口初始化。(这里是本机循环的IP地址,自己写入自己读取)
int s;struct sockaddr_in server_addr;s = socket(AF_INET,SOCK_STREAM,0);if(s < 0){printf("socket error \n");return -1;}bzero(&server_addr,sizeof(server_addr));server_addr.sin_family = AF_INET;server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");server_addr.sin_port = htons(Port);
然后是connect函数发送连接请求,s是客户端套接字(因为系统会分配端口,所以不用bind()再进行绑定,详细请看第一篇文章)这里客户端套接字向服务器端套接字发送连接请求,如果返回-1,说明请求连接失败。
if (connect(s, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) < 0) {perror("connect error");return -1;}
接着我们要对客户端套接字进行读取和写入的处理:如下面的函数所示,建立完连接之后,进入读写的循环,这里是从标准输入0(终端输入)读取,向服务器端写入。
int process_conn_server(int s){ssize_t size = 0;char buffer[1024] = {0} ;char message [100] = {0};for(;;){memset(buffer, 0, sizeof(buffer));size = read(0,message,sizeof(message));if(size == 0){return -1;}sprintf(buffer,"message: %s ",message);write(s,buffer,strlen(buffer));}return 0;
}
至此我们的客户端的功能全部实现,下面是完整的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>#define Port 8888int process_conn_server(int s){ssize_t size = 0;char buffer[1024] = {0} ;char message [100] = {0};for(;;){memset(buffer, 0, sizeof(buffer));size = read(0,message,sizeof(message));if(size == 0){return -1;}sprintf(buffer,"message: %s ",message);write(s,buffer,strlen(buffer));}return 0;
}int main(int argc,char* argv[]){int s;struct sockaddr_in server_addr;s = socket(AF_INET,SOCK_STREAM,0);if(s < 0){printf("socket error \n");return -1;}bzero(&server_addr,sizeof(server_addr));server_addr.sin_family = AF_INET;server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");server_addr.sin_port = htons(Port);if (connect(s, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) < 0) {perror("connect error");return -1;}process_conn_server(s);close(s);return 0;
}
最后我们要实现服务器端和客户端的通信:
首先是创建一个makefile文件,用来编译生成两个目标程序:server和client。
CC = gcc
CFLAGS = -Wall -g
TARGETS = server clientall: $(TARGETS)server: server.c$(CC) $(CFLAGS) -o server server.cclient: client.c$(CC) $(CFLAGS) -o client client.cclean:rm -f $(TARGETS)

先去确认一下client.c和server.c以及makefile都在同一个文件夹路径下,然后进入我们的终端,注意是要在三个文件的文件夹路径下,执行make指令来进行编译。这里因为我编译过了,所以提示没有改变,如果没有编译过,会提示生成了可执行文件。

然后在两个终端中分别执行服务器端的程序和客户端程序:
现在你可以尝试着在客户端发送一些字符了,因为我的代码的程序是客户端从终端读取,写入到服务器端,服务器端读取,写入到终端去。所以会出现下面的结果,可以看到服务器端的终端成功打印了代码,至于为啥有两个换行,我认为是在客户端输入到终端的时候需要回车多输入了一个换行符,这个可以自行进行修改。
自此,我们的服务器端和客户端之间的通信可以正常运行了,当然你可能会遇到不同的问题:
首先就是客户端connect error的问题,这是因为要先开启服务器端的程序,然后再开启客户端的程序,因为accept()是阻塞的,等待连接请求。
其次可能出现 bind error的问题,这是因为你的刚运行的服务器端的程序的端口还在被占用(即使你关闭了程序),不用担心,系统会回收端口,等一会就可以继续使用该端口。
我目前还没有尝试不同设备之间的通信,但是我认为是没有问题的:我打印了客户端的端口会发现是系统分配的端口,只是没有测试不同IP。

最后十分感谢阅读,希望文章内容对你有所帮助,如有错误欢迎指出。
相关文章:
TCP网络编程(三)—— 客户端的编写/服务器端和客户端的通信
上篇文章我们学习了TCP的服务器端模式的编写,这篇文章我们将开始编写客户端的代码,完成服务器端和客户端的通信。完整代码和演示在文章的后面。 和服务器端不同,在客户端我们只需要服务器端的套接字和服务器端的地址和端口,用于向…...
如何在谷歌浏览器中使用自定义模板
作为最常用的网络浏览器之一,谷歌浏览器不仅提供了强大的功能,还允许用户通过各种方式自定义其外观和功能。其中,使用自定义模板可以极大地提升用户体验,无论是更改浏览器的外观还是优化网页显示效果。本文将详细介绍如何在谷歌浏…...
Day2 微服务 网关路由转发、网关登录校验、配置管理
目录 1.网关路由转发 1.1 网关 1.2 快速入门 1.2.1 创建项目 1.2.2 引入依赖 1.2.3 启动类 1.2.4 配置路由 1.2.5 测试 1.3 路由过滤 2.网关登录校验 2.1 鉴权思路分析 2.2 网关过滤器 2.3 自定义过滤器 2.3.1 自定义GatewayFilter 2.3.2 自定义GlobalFilter 2.4 登录校验 2.4.…...
Android 旋转盘导航栏
1.直接上源码: package com.you.arc;import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Point; import android.graphics.RectF; import android.support…...
空域降噪、频域降噪和时域降噪
目录 算法原理: 1.图像噪声 2.图像中常见的噪声的类型 3.不同域的定义 4.空域降噪 4.1.空域降噪的定义: 4.2.思想核心: 4.3.局部的线性算法 高斯降噪 4.4.非局部算法 5.频域降噪 傅里叶降噪: 小波降噪: …...
Cornerstone3D:了解Nifti文件,并查看元数据
Nifti 全称Neuroimaging Informatics Technology Initiative是一种专为存储医学和神经影像数据而设计的文件格式。设计目的是高效的存储三维或四维图像数据,同时将相关的元数据紧凑地嵌入文件中。Nifti文件的组成:头信息(元数据)…...
设计模式の状态策略责任链模式
文章目录 前言一、状态模式二、策略模式三、责任链模式 前言 本篇是关于设计模式中的状态模式、策略模式、以及责任链模式的学习笔记。 一、状态模式 状态模式是一种行为设计模式,核心思想在于,使某个对象在其内部状态改变时,改变该对象的行为…...
DevOps流程CICD之Jenkins使用操作
一、jenkins的docker-compose安装部署 请参考 jenkins的docker安装部署配置全网最详细教程-CSDN博客 二、创建repository 三、创建ssh 四、创建视图 五、创建任务 六、配置gitlab钩子 七、自动构建部署CI/CD验证...
【玩转23种Java设计模式】行为型模式篇:备忘录模式
软件设计模式(Design pattern),又称设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。 汇总目录链接&…...
Unity Shader TexelSize的意义
TexelSize在制作玻璃折射效果时会用到。 // Get the normal in tangent space fixed3 bump UnpackNormal(tex2D(_BumpMap, i.uv.zw)); // Compute the offset in tangent space float2 offset bump.xy * _Distortion * _RefractionTex_TexelSize.xy; i.scrPos.xy offset * i…...
三、STM32MP257系列之定制Yocto Machine
文章目录 STM32MP257系列之定制的Yocto Machine1. TFA 定制2. OPTEE OS定制3. Uboot 定制3.1 创建 board3.2 创建 board的头文件3.3 创建 board的配置文件3.4 添加我们自己的dtb文件3.5 生成新patch打包到uboot recipe中3.6 修改yocto中的配置 4. Kernel 定制4.1 定制设备树 5.…...
小程序信息收集(小迪网络安全笔记~
免责声明:本文章仅用于交流学习,因文章内容而产生的任何违法&未授权行为,与文章作者无关!!! 附:完整笔记目录~ ps:本人小白,笔记均在个人理解基础上整理,…...
使用 Docker 搭建 Drogon 框架
使用 Docker 搭建 Drogon 框架 Drogon 是一个基于 C 的高性能 Web 框架,支持异步 I/O 和协程。使用 Docker 可以快速搭建 Drogon 开发环境,避免依赖冲突和配置问题。 以下是使用 Docker 搭建 Drogon 框架的详细步骤: 1. 准备工作 安装 Doc…...
【Linux报告】实训一:GNME桌面环境的设置及应用
实训一:GNME桌面环境的设置及应用 【练习1】在图形模式和文本模式下登录Linux系统。 1、开启Linux虚拟机。 答:打开此虚拟机如图所示 2、观察屏幕上显示的启动信息。 3、当系统启动到图形界面时,用普通用户身份登录。 答:如图…...
活动预告 |【Part1】Microsoft Azure 在线技术公开课:基础知识
课程介绍 参加“Azure 在线技术公开课:基础知识”活动,培养有助于创造新的技术可能性的技能并探索基础云概念。参加我们举办的本次免费培训活动,扩充自身的云模型和云服务类型知识。你还可以查看以计算、网络和存储为核心的 Azure 服务。 活…...
vulnhub靶场【Hogwarts】之bellatrix
前言 靶机:hotwarts-dobby,ip地址为192.168.1.69 攻击:kali,ip地址为192.168.1.16 都采用虚拟机,网卡为桥接模式 主机发现 使用arp-scan -l或netdiscover -r 192.168.1.1/24扫描发现主机 信息收集 使用nmap扫描端…...
移动 APP 设计规范参考
一、界面设计规范 布局原则: 内容优先:以内容为核心进行布局,突出用户需要的信息,简化页面导航,提升屏幕空间利用率.一致性:保持界面元素风格一致,包括颜色、字体、图标等,使用户在…...
HarmonyOS:@Require装饰器:校验构造传参
一、前言 Require是校验Prop、State、Provide、BuilderParam和普通变量(无状态装饰器修饰的变量)是否需要构造传参的一个装饰器。 说明 从API version 11开始对Prop/BuilderParam进行校验。 从API version 11开始,该装饰器支持在元服务中使用。 从API version 12开…...
github提交不上去,网络超时问题解决
问题出现的原因: DNS服务器数据不同步,github的服务器发送迁移,在本地缓存的ip地址现在无效了。 解决方案: 1)点击这里,查询github.com最新的ip地址 2.0)编辑linux系统地址缓存文件&#x…...
国产数据库OceanBase从入门到放弃教程
1. 介绍 是由蚂蚁集团(Ant Group,原蚂蚁金服)自主研发的分布式关系型数据库。它旨在解决海量数据存储和高并发访问的问题,特别适合金融级应用场景,如支付宝等对数据一致性、可靠性和性能有极高要求的服务。以下是关于…...
从Quill光标到用户头像:手把手教你为Yjs协同编辑器添加完整的在线用户列表(附状态同步技巧)
从Quill光标到用户头像:构建企业级协同编辑器的完整用户感知系统 在数字化办公场景中,协同编辑器的用户体验往往决定了团队协作效率的上限。当多个用户同时编辑同一份文档时,简单的光标显示已无法满足现代团队对协作透明度的需求。本文将深入…...
从Simulink模型到S32K3xx芯片:手把手教你玩转NXP官方MBD工具包(v1.4实战)
从Simulink模型到S32K3xx芯片:手把手教你玩转NXP官方MBD工具包(v1.4实战) 在汽车电子开发领域,时间就是竞争力。当传统手写代码遇上复杂的汽车MCU外设配置,工程师们常常陷入寄存器手册的海洋。而基于模型的设计&#x…...
cimgui生成器完全解析:从Lua脚本到C接口的魔法转换 [特殊字符]
cimgui生成器完全解析:从Lua脚本到C接口的魔法转换 🎯 【免费下载链接】cimgui c-api for imgui (https://github.com/ocornut/imgui) Look at: https://github.com/cimgui for other widgets 项目地址: https://gitcode.com/gh_mirrors/ci/cimgui …...
从理论到代码:一步步拆解单纯形法在MATLAB中的核心‘旋转运算’
从理论到代码:一步步拆解单纯形法在MATLAB中的核心‘旋转运算’ 单纯形法作为线性规划领域最经典的算法之一,其理论优雅性与计算高效性在数学优化中独树一帜。然而,当我们将教科书中的表格计算转化为编程语言实现时,往往会遇到一个…...
CRM功能解析:覆盖客户、销售、数据、库存、工单全场景
在数字化转型浪潮中,企业对业务管理系统的需求已从单一CRM延伸至客户分层、销售自动化、数据分析、进销存、工单协同的全链路覆盖。不同系统在核心能力的实现逻辑与落地价值上差异显著,本文选取超兔一体云、Attio、Creatio、伙伴云CRM、OKKICRMÿ…...
论基于云原生数据库的企业信息系统架构设计
基于云原生数据库的企业架构随着云原生技术的全面普及,企业信息系统对架构的弹性伸缩、高可靠性、资源高效利用及敏捷迭代能力提出了更高要求。传统数据库存在的存储与计算耦合、扩展能力受限、运维成本高、故障恢复慢等痛点,已难以适配现代化企业的业务…...
3个实战场景掌握Kafka-UI:高效管理Apache Kafka集群的实用指南
3个实战场景掌握Kafka-UI:高效管理Apache Kafka集群的实用指南 【免费下载链接】kafka-ui Open-Source Web UI for managing Apache Kafka clusters 项目地址: https://gitcode.com/gh_mirrors/kaf/kafka-ui Kafka-UI是一款专业的开源Web界面工具,…...
自驱动关节臂坐标测量机精度提升理论与技术【附程序】
✨ 长期致力于自驱动关节臂坐标测量机、关节模组、结构参数误差、动态综合误差、最佳测量区研究工作,擅长数据搜集与处理、建模仿真、程序编写、仿真设计。 ✅ 专业定制毕设、代码 ✅ 如需沟通交流,点击《获取方式》 (1)关节模组转…...
STM32F103驱动TM1650数码管:从硬件连接到完整代码的保姆级避坑指南
STM32F103驱动TM1650数码管:从硬件连接到完整代码的保姆级避坑指南 第一次接触STM32F103和TM1650数码管模块时,我像大多数嵌入式新手一样,以为按照教程连接几根线、复制几段代码就能轻松点亮数码管。直到实际动手才发现,从硬件连接…...
告别手写解析!用Python Cantools 39.4.5一键生成CAN/CANFD DBC的C代码(附批处理脚本)
从DBC到C代码:Python Cantools全自动转换实战指南 在汽车电子和嵌入式开发领域,CAN总线通信是核心基础设施,而DBC文件则是定义CAN/CANFD通信协议的行业标准。传统开发流程中,工程师需要手动解析DBC文件并编写大量信号打包/解包代码…...
