C语言Socket编程,实现两个程序间的通信

2023-05-16

文章目录

  • server和client通信流程图
  • 实现两个程序间的通信
    • 1.服务端server
    • 2.客户端client
    • 3.怎么运行呢?
    • 4.重写代码

已剪辑自: https://www.cnblogs.com/fisherss/p/12085123.html

server和client通信流程图

在mooc上找到的,使用Socket客户端client和服务端server通信的流程图👇

imgimg

实现两个程序间的通信

1.服务端server

  • 服务端需要 "两个"套接字 :

    • 1.服务端套接字serverSocket

    • 2.客户端connect连接请求时,发来的套接字clientSocket

  • 按流程图来看, server服务端主要就是实现下面几个步骤:

    • 0.WSAStartup初始化 //这个东西也不知道是什么鬼,反正就是要初始化一下,不初始化会创建socket失败!
    • 1.服务端套接字 = socket(); //获取一个套接字对象吧?
    • 2.bind(服务端套接字); //绑定
    • 3.listen(服务端套接字); //监听
      —这个时候客户端就可以发连接请求到服务端了,此时服务端会用accept阻塞进程,直到获取客户端发来的请求—
    • 4.客户端套接字 = accept(); //收到客户端发来的请求,accept返回客户端的套接字对象
    • 5.recv(客户端套接字,要发的消息message) //recv会阻塞进程,直到客户端发送消息过来
      ----printf(message)把接收到的消息打印出来-----
    • 6.send(客户端套接字,要发的消息message) //服务端也可以使用send,向客户端发送消息
      —这里可以循环,跳转回到步骤3.accept 开启新一轮的接收请求—
    • 7.closesocket(客户端套接字);

所以服务端代码可以这样写👇
在CSDN上copy的,原来的代码需要在linux环境下运行,在windows下需要更改很多头文件,和一些函数,wsastartup这个东西也需要初始化一下。
改了之后,一个可以用的服务端server代码👇

复制
#include <sys/stat.h>
#include <fcntl.h>
#include <winsock2.h>
#include <windows.h>
#pragma comment(lib, "wsock32.lib")
#include <errno.h>
#include<stdlib.h>
#include<string.h>
#include <sys/types.h>
#include<ws2tcpip.h>
#include <stdio.h>
#include <unistd.h>
#define SERVER_PORT 6666
 
/*
监听后,一直处于accept阻塞状态,
直到有客户端连接,
当客户端如数quit后,断开与客户端的连接
*/
 
int main()
{
 
	//调用socket函数返回的文件描述符
	int serverSocket;
	 
	//声明两个套接字sockaddr_in结构体变量,分别表示客户端和服务器
	struct sockaddr_in server_addr;
	struct sockaddr_in clientAddr;
	 
	int addr_len = sizeof(clientAddr);
	int client;
	char buffer[200]; //存储 发送和接收的信息 
	int iDataNum;

	//必须先初始化 
	WSADATA wsaData;
	WSAStartup(MAKEWORD(2,2),&wsaData);
	if(LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) !=2){
	    printf("require version fail!");
	    return -1;
	}
	
	//socket函数,失败返回-1
	//int socket(int domain, int type, int protocol);
	//第一个参数表示使用的地址类型,一般都是ipv4,AF_INET
	//第二个参数表示套接字类型:tcp:面向连接的稳定数据传输SOCK_STREAM
	//第三个参数设置为0
	//建立socket
	if((serverSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) < 0)
	{
		perror("socket");
		return 1;
	}
	
	//初始化 server_addr
	memset(&server_addr,0, sizeof(server_addr));
	 
	//初始化服务器端的套接字,并用htons和htonl将端口和地址转成网络字节序
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(SERVER_PORT);
	 
	//ip可是是本服务器的ip,也可以用宏INADDR_ANY代替,代表0.0.0.0,表明所有地址
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	 
	//对于bind,accept之类的函数,里面套接字参数都是需要强制转换成(struct sockaddr *)
	//bind三个参数:服务器端的套接字的文件描述符,
	if(bind(serverSocket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
	{
		perror("connect");
		return 1;
	}
	 
	//设置服务器上的socket为监听状态
	if(listen(serverSocket, 5) < 0)
	{
		perror("listen");
		return 1;
	}
	
	//循环 接收消息、发送消息 
	while(1)
	{ 
		printf("监听端口: %d\n", SERVER_PORT);
		
		//调用accept函数后,会进入阻塞状态
		//accept返回一个套接字的文件描述符,这样服务器端便有两个套接字的文件描述符,
		//serverSocket和client。
		//serverSocket仍然继续在监听状态,client则负责接收和发送数据
		//clientAddr是一个传出参数,accept返回时,传出客户端的地址和端口号
		//addr_len是一个传入-传出参数,传入的是调用者提供的缓冲区的clientAddr的长度,以避免缓冲区溢出。
		//传出的是客户端地址结构体的实际长度。
		//出错返回-1
		
		client = accept(serverSocket, (struct sockaddr*)&clientAddr, (socklen_t*)&addr_len);
		
		if(client < 0)
		{
			perror("accept");
			continue;
		}
		 
		printf("等待消息...\n");
		
		//inet_ntoa ip地址转换函数,将网络字节序IP转换为点分十进制IP
		//表达式:char *inet_ntoa (struct in_addr);
		printf("IP is %s\n", inet_ntoa(clientAddr.sin_addr)); //把来访问的客户端的IP地址打出来
		printf("Port is %d\n", htons(clientAddr.sin_port)); 
		 
		while(1)
		{
			buffer[0] = '\0';
			iDataNum = recv(client, buffer, 1024, 0);
			if(iDataNum < 0)
			{
	//			perror("recv null");
				continue;
			}
			buffer[iDataNum] = '\0';
			if(strcmp(buffer, "quit") == 0) break;
			printf("收到消息: %s\n", buffer);
			printf("发送消息:");
			scanf("%s", buffer);
			send(client, buffer, strlen(buffer), 0); //服务端也向客户端发送消息 
			if(strcmp(buffer, "quit") == 0) break; //输入quit停止服务端程序 
		}
	}
	 
	close(serverSocket);
	 
	return 0;
 
}

2.客户端client

  • 客户端只需要 "1个"套接字 :
    • 1.服务端套接字serverSocket
  • 按流程图来看, client客户端主要就是实现下面几个步骤:
    • 0.WSAStartup初始化 //这个东西也不知道是什么鬼,反正就是要初始化一下,不初始化会创建socket失败!
    • 1.服务端套接字 = socket(); //获取一个套接字对象
    • 2.connect(服务端套接字); //connect连接服务端
      —这个时候客户端就可以发数据到服务端了,此时服务端会用recv阻塞进程,直到获取客户端发来的数据—
    • 3.send(服务端套接字,要发的消息message)
    • 4.recv(服务端套接字,收到的message) //客户也可以用recv收消息的,recv会阻塞进程,直到服务端发送消息过来
      —printf(message)把接收到的消息打印出来—
      —这里可以循环,跳转回到步骤3.send 开启新一轮的接收请求—
    • 5.closesocket(客户端套接字);

也是在CSDN上copy的代码,改了之后,一个可以用的客户端client代码👇

复制#include <sys/stat.h>
#include <fcntl.h>
#include <winsock2.h>
#include <windows.h>
#pragma comment(lib, "wsock32.lib")
#include <errno.h>
#include<stdlib.h>
#include<string.h>
#include <sys/types.h>
#include<ws2tcpip.h>
#include <stdio.h>
#include <unistd.h>
#define SERVER_PORT 6666
 
int main()
{
 
	//客户端只需要一个套接字文件描述符,用于和服务器通信
	int serverSocket;
	 
	//描述服务器的socket
	struct sockaddr_in serverAddr;
	 
	char sendbuf[200]; //存储 发送的信息 
	char recvbuf[200]; //存储 接收到的信息 
	 
	int iDataNum;
	
	//下面代码初始化 
	WSADATA wsaData;
	WSAStartup(MAKEWORD(2,2),&wsaData);
	if(LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) !=2){
	    printf("require version fail!");
	    return -1;
	}
	
	if((serverSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) < 0)
	{
		perror("socket");
		return 1;
	}
	 
	serverAddr.sin_family = AF_INET;
	serverAddr.sin_port = htons(SERVER_PORT);
	 
	//指定服务器端的ip,本地测试:127.0.0.1
	//inet_addr()函数,将点分十进制IP转换成网络字节序IP
	serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
	 
	if(connect(serverSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0)
	{
		perror("connect");
		return 1;
	}
	 
	printf("连接到主机...\n");
	 
	while(1)
	{
		printf("发送消息:");
		scanf("%s", sendbuf);
		printf("\n");
		send(serverSocket, sendbuf, strlen(sendbuf), 0); //向服务端发送消息
		if(strcmp(sendbuf, "quit") == 0) break;
		printf("读取消息:");
		recvbuf[0] = '\0';
		iDataNum = recv(serverSocket, recvbuf, 200, 0); //接收服务端发来的消息
		recvbuf[iDataNum] = '\0';
		printf("%s\n", recvbuf);
	}

	close(serverSocket);
 
	return 0;
}

3.怎么运行呢?

首先编译server.c和client.c这两个c语言,build-compile成.exe文件
用devcpp编译器也可以编译的,不一定一定要用codeblock。。
如果用devcpp上面的代码编译出错,需要把devcpp设置一下编译选项,参考链接
img

主要运行步骤👇

0.确认程序已经编译成功生成了exe文件。
1.先运行服务端server.exe
2.再运行客户端client.exe
3.就可以在client程序里输入消息到服务端了,服务端会收到消息,也能向客户端发消息

这里可以用一下cmd命令符打开运行文件👇
运行---->cmd

打开cmd,运行server服务端程序

复制D:                  //先进入程序存放的磁盘,比如 D: 或者 C: 或者 F:
cd fishers  //cd C语言程序服务端server所在的目录,比如cd 2017xxx/MyTest
server   //直接输入服务端程序的名称,运行server.exe程序,

打开cmd,运行client客户端程序

复制D:                  //先进入程序存放的磁盘,比如 D: 或者 C: 或者 F:
cd fishers  //cd C语言程序客户端client所在的目录,比如cd 2017xxx/MyTest
client   //直接输入客户端程序的名称,运行client.exe程序

然后就可以在client上输入想要发送的消息了👇

img

按步骤来的视频,配置编译器,编译,运行server.exe,运行client.exe,发消息👇

主要是理解客户端和服务端通信的流程
img

4.重写代码

然后上面是CSDN的代码,理解原理后就可以自己改写server.c和client.c,实现两个程序间基于socket的通信

理解原理:https://blog.csdn.net/jinmie0193/article/details/78951055

server.c👇

img
img

client.c👇

img

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C语言Socket编程,实现两个程序间的通信 的相关文章

  • 一篇文章快速搞懂Qt文件读写操作

    已剪辑自 https www cnblogs com jfzhu p 13546886 html 导读 xff1a Qt当中使用QFile类对文件进行读写操作 xff0c 对文本文件也可以与QTextStream一起使用 xff0c 这样读
  • 完整的PRD文档包含哪些内容?

    完整的PRD文档包含哪些内容 xff1f 千万 xff0c 千万 xff0c 千万别再套模板写需求文档了 xff0c 要想写好需求文档重要的不是包含哪些内容 xff0c 而是为什么包含这些内容 xff01 话不多说 xff0c 直接上干货
  • 分享一个开源的QT的串口示波器

    已剪辑自 https mp weixin qq com s XHELtvZ Wk2hNzsWD52D1w 直接来源 果果小师弟 逛github时看到这个QT的串口示波器 xff0c 完全开源 xff0c 支持串口 TCP 波形显示 通信协议
  • C 语言函数返回值,竟也有潜规则~

    已剪辑自 https mp weixin qq com s WNHx1zhna8iGaYIj6 3 fg 基本上 xff0c 没有人会将大段的C语言代码全部塞入 main 函数 更好的做法是按照复用率高 耦合性低的原则 xff0c 尽可能的
  • 模型在物理学发展中的作用

    已剪辑自 https mp weixin qq com s txS CQAIXPtY6kb2tHukUQ 模型是物理学认识由唯象理论过渡到动力学理论重要的环节 开普勒的行星运行模型 气体的分子运动模型 爱因斯坦的光子模型 卢瑟福 玻尔的原子
  • 第一性原理谈安全性和可靠性

    已剪辑自 https mp weixin qq com s jttd dhv9PmNu25Z zyd5Q 最近从各个行业对系统的安全性的关注度越来越高 xff0c 10月28日 xff0c 工信部公开征求的 道路机动车辆生产准入许可管理条例
  • 在浏览器地址栏输入一个URL后回车,背后会进行哪些技术步骤?

    转载于 xff1a 小林的图解网络系列 关键是要有个上帝视角 xff0c 先要有个网络模型的概念 xff0c 也就是TCP IP 四层网络模型 xff0c 然后针对每一层的协议进行深入 学习计算机网络一定要抓主一个点 xff0c 就是 输入
  • 在MacOS上实现两个网络调试助手的UDP通信测试

    文章目录 一 背景二 网络调试助手软件三 UDP通信过程 一 背景 因为有一个项目要中会使用本机中两个应用程序之间的UDP通信 因此本文记录一下怎么在MacOS上实现两个网络调试助手的UDP通信测试 二 网络调试助手软件 我使用的网络调试助
  • QT和网络调试助手之间的UDP通信

    文章目录 一 背景二 实现过程简述UDP协议工作原理及编程模型UDP 接收端UDP 发送端运行UDP接收端和发送端运行UDP发送端发送数据给网络调试助手 一 背景 之前一篇博客实现了两个网络调试助手之间的UDP通信 文章链接 xff1a 在
  • 一个开源且完全自主开发的国产网络协议栈

    已剪辑自 https mp weixin qq com s 1LE7mGc9mRuajRgNsyirQ onps是一个开源且完全自主开发的国产网络协议栈 xff0c 适用于资源受限的单片机系统 xff0c 提供完整地ethernet ppp
  • PyQt的使用

    使用conda切换到python3 如果不会使用conda xff0c 那么安装anaconda后打开navigator xff0c 再environments中选择创建好的python3环境 xff0c 右键打开terminal即可 安装
  • 前后台系统及嵌入式前后台模式实时性优化

    一 前后台系统 前后台系统 xff0c 即计算机前后台系统 xff0c 早期的嵌入式系统中没有操作系统的概念 xff0c 程序员编写嵌入式程序通常直接面对裸机及裸设备 xff0c 在这种情况下 xff0c 通常把嵌入式程序分成两部分 xff
  • 又一嵌入式开源仿真器

    已剪辑自 https mp weixin qq com s X0I3EotJ8TRqLK8vb8iQvA 同QEMU类似 xff0c Renode也是嵌入式相关的一个模拟器 Renode 针对物联网应用 xff0c QEMU 针对 PC 模
  • SkyEye天目全数字实时仿真软件功能介绍

    文章目录 SkyEye的概念和应用 SkyEye的优势 SkyEye可与第三方语言或者模型集成 基于可视化图形的硬件建模 容器化的仿真平台 FPGA协同仿真 SkyEye的应用案例 SkyEye大规模航电系统仿真案例 SkyEye 飞行器显
  • SkyEye——如何实现1553B总线仿真?

    已剪辑自 https www digiproto com news 204 html 1553B最初是美国军方专为飞机上设备制定的一种信息传输总线标准 xff0c 具有双向传输的特性 xff0c 实时性和可靠性高 xff0c 现已广泛应用于
  • 细数SkyEye异构仿真的5大特色

    已剪辑自 https www digiproto com news 65 html 航天飞行器使用仿真器的重要性 航天飞行器如卫星 载人飞船等需要在空中运行很长的时间 xff0c 如果出现问题回收再调试可能要历时几个月 xff0c 而且不得
  • SkyEye:航空发动机控制系统仿真

    已剪辑自 https www digiproto com news 212 html 航空发动机 xff08 aero engine xff09 是一种高度复杂和精密的热力机械 xff0c 作为飞机的心脏 xff0c 不仅是飞机飞行的动力
  • 基于功能安全的车载计算平台开发:软件层面

    已剪辑自 https mp weixin qq com s SIBvH8u vCk6W28KrPBmA 车载智能计算平台作为智能汽车的安全关键系统 xff0c 软件层面的安全性至关重要 由于车载智能计算平台功能丰富 xff0c 应用场景复杂
  • 软件和硬件中的调用

    文章目录 1 概述 2 1 程序进程内的调用 xff1a 函数调用 2 2 程序进程间的调用 xff1a IPC 2 3 远程程序调用 xff1a RPC 2 4 远程调用REST 3 硬件 调用 3 1 综述 总线模型 3 2 片内的总线
  • 软件和硬件之间的数据交互接口

    已剪辑自 链接 编者按 软件和硬件 xff0c 既相互依存又需要某种程度上的相互独立 通过软件和硬件之间的接口把两者连接在一起 软硬件接口 xff0c 有很多含义 xff1a 比如指令集是CPU软件和硬件之间的接口 xff1b 比如一些硬件

随机推荐

  • 硬件定义软件?还是,软件定义硬件?

    文章目录 1 软件和硬件 1 1 软件和硬件的定义 1 2 硬件定义软件 和 软件定义硬件 的定义 1 3 CPU xff0c 软件和硬件解耦 1 4 CPU的软硬件定义 2 硬件定义软件 2 1 系统从软件逐步到硬件 2 2 硬件架构决定
  • Matlab下多径衰落信道的仿真

    衰落信道参数包括多径扩展和多普勒扩展 时不变的多径扩展相当于一个延时抽头滤波器 xff0c 而多普勒扩展要注意多普勒功率谱密度 xff0c 通常使用Jakes功率谱 高斯 均匀功率谱 多径衰落信道由单径信道叠加而成 xff0c 而单径信道中
  • 硬件接口和软件接口

    文章目录 硬件接口IDESCSISATA光纤通道游戏设备RAID卡USBMD设备MP3视频音频 软件接口Java里的接口面向对象的接口 聊聊软件接口1 什么是接口2 诞生3 早期 xff08 1950 1970 xff09 4 快速发展 x
  • 有关C语言,定时器,周期任务的一些文章汇总

    测试C语言中打印一句 hello world需要耗费多少时间 C C 43 43 开源库 适合嵌入式的定时器调度器 C语言实现的多线程定时器 C语言操作时间函数 xff0c 实现定时执行某个任务小程序 C语言实现任务调度与定时器 Linux
  • SCADE简单了解

    随着新能源三电 智能驾驶等新技术的应用 xff0c 汽车中衍生出很多的安全零部件 xff0c 如BMS VCU MCU ADAS等 xff0c 相应的软件在汽车中的比重越来越大 xff0c 随之而来的安全性 可靠性要求也越来越高 ANSYS
  • 冯诺依曼体系结构与操作系统

    文章目录 详解冯诺依曼体系结构与操作系统前言1 简要背景介绍2 五大部件介绍3 细节解释4 举例理解冯诺依曼机中数据走向 二 全面认识操作系统1 操作系统的概念2 计算机系统 比对 银行系统3 深入认识 管理 xff1a 5 操作系统存在的
  • ADAS系统安全架构设计及安全等级的分解

    已剪辑自 https mp weixin qq com s PaFQDUR iOnEeueYQ82m w 笔者从事功能安全领域工作八年有余 xff0c 结合个人经验分享一下对系统安全架构设计的理解 xff0c 希望能够解决部分同行对于安全架
  • 汽车电子电气架构演进驱动主机厂多重变化

    已剪辑自 https mp weixin qq com s P56MaFODVc eZ4JEOVJvfA 汽车电子电气架构 xff08 EEA xff0c Electrical Electronic Architecture xff09 把
  • 编写可移植C/C++程序的要点

    以前做过两年C C 43 43 程序移植工作 xff0c 从Win32平台移植到Linux平台 大约有上百万行C C 43 43 代码 xff0c 历时一年多 在开发Win32版本时 xff0c 已经强调了程序的可植性 xff0c 无奈Wi
  • 智能座舱域控制器技术发展趋势分析

    已剪辑自 https mp weixin qq com s ajmpg7ThTUBerLvb2Bng9g 提到座舱域控制器用的主控SoC芯片 xff0c 大家第一个会想到应该就是高通的SA8155P 目前 xff0c 在主机厂新上市的中高端
  • 一个单片机驱动LCD编程思路

    文章目录 LCD种类概述TFT lcdCOG lcdOLED lcd 硬件场景预备知识面向对象驱动与设备分离 LCD到底是什么LCD驱动框架代码分析GUI和LCD层驱动IC层接口层总体流程 用法和好处字库声明 已剪辑自 https mp w
  • TinyFlashDB:一种超轻量的可纠错的通用单片机Flash存储方案

    文章目录 一 TinyFlashDB设计理念二 TinyFlashDB使用示例三 TinyFlashDB API介绍四 TinyFlashDB设计原理五 TinyFlashDB移植和配置六 移植到STM32单片机 已剪辑自 https mp
  • VR游戏交互开发的一些体验

    VR游戏交互开发的一些体验 本文主要写Unity开发手游过程中VR交互输入控制的一些浅薄的经验交互方面 xff0c 头控和视线按钮依然较为主流 xff0c 可以获得传感器数据来获得输入除了实体按钮输入之外还可以探索其他交互方式 xff0c
  • FTP、FTPS和SFTP的简介与区别

    FTP FTPS和SFTP的简介与区别 参考链接 xff1a https blog csdn net Mr Fan97 article details 119539189 FTP FTPS和SFTP简介 FTP FTP 即 文件传输协议 x
  • 基于功能安全的车载计算平台开发:硬件层面

    作为车载智能计算平台功能软件与系统软件的载体 xff0c 硬件的失效可能直接导致功能软件输出不可信任的结果 xff0c 从而违背安全目标 由于硬件故障在硬件生命周期中发生时间的随机性 xff0c 在通过改善流程降低系统性失效的同时 xff0
  • 基于功能安全的车载计算平台开发:系统层面

    相对于功能安全概念阶段 xff0c 系统阶段更专注于产品的详细设计 xff0c 涉及系统工程 安全工程和架构设计等不同技术领域 同时 xff0c 系统阶段也经常扮演着供应链上 下游功能安全的DIA交互阶段 xff0c 是功能安全中非常重要且
  • 神器必会!特别好使的编辑器Source Insight

    已剪辑自 https mp weixin qq com s nA9VJeMjC4gDpDSI8r 2FA Source Insight xff08 以下简称SI xff09 是世界上最好的编辑器 xff0c 说这句话不知道会不会出门被打呢
  • QT-GUI应用程序设计基础

    这里有一个容易搞混的点 xff0c 那就是widget h中的命名空间中的类Widget和在该文件中定义的类Widget不是同一个类 这其实也是很好理解的 xff0c 命名空间的作用其实就是将变量和类型的作用范围给控制起来 xff0c 这样
  • QT中怎么设置定时器/周期任务/定时触发任务

    Qt中定时器的使用有两种方法 xff0c 一种是使用QObject类提供的定时器 xff0c 还有一种就是使用QTimer类 其精确度一般依赖于操作系统和硬件 xff0c 但一般支持20ms 下面将分别介绍两种方法来使用定时器 QObjec
  • C语言Socket编程,实现两个程序间的通信

    文章目录 server和client通信流程图实现两个程序间的通信1 服务端server2 客户端client3 怎么运行呢 xff1f 4 重写代码 已剪辑自 https www cnblogs com fisherss p 120851