TCP/IP C 语言实现单个客户端和服务端 TCP 通信

 这是多线程服务端

#include <stdio.h>
#include <winsock2.h>
#include <pthread.h>
#include <string.h>
#include <conio.h>
#pragma comment(lib,"ws2_32.lib")
#pragma warning(disable : 4996)	
// 客户端结构体
typedef struct ThreadNode
{int index;pthread_t* Thread;SOCKET Client;struct ThreadNode * next;ThreadNode(){index = 0;this->next = NULL;}
} hThread;
// 增加客户端结构体
hThread *clientHeadNote, *clientEndNote;
hThread * addClient()
{hThread * ClientNote = new hThread();return ClientNote;
}
// 每个建立链接的客户端分配一个函数,每个线程运行一个这样的函数
void* ThreadClient(void*)
{if (clientEndNote == NULL){printf("empty Link\n");return 0;}char revData[255];SOCKET sClient = clientEndNote->Client;printf("client logged in \n");while (1){int ret = recv(sClient, revData, 255, 0);		// 接收数据if (ret > 0){revData[ret] = 0x00;printf(revData);printf("\n");if (strcmp("log_out", revData) == 0)		// 新功能:加入客户端控制签退{char a[255];strcpy(a, "已注销\n");send(sClient, a, 255, 0);				// 反馈:向客户端sClienr发送“已注销”消息,发送长度为255个字节,1是指不阻塞。closesocket(sClient);printf("签退成功\n");}else{char a[255];strcpy(a, "服务器已收到消息\n");send(sClient, a, 255, 0);}}}closesocket(sClient);
}int main(int argc, char* argv[])
{// 初始化WSAWORD sockVersion = MAKEWORD(2, 2);WSADATA wsaData;if (WSAStartup(sockVersion, &wsaData) != 0){return 0;}// 创建套接字:AF_INET:TCP/IP 协议,数据流,TCP 传输 SOCKET slisten = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (slisten == INVALID_SOCKET){printf("socket error !");return 0;}//绑定IP和端口sockaddr_in sin;sin.sin_family = AF_INET;sin.sin_port = htons(8888);								// 端口和客户端端口要相同,否则链接建立不上sin.sin_addr.S_un.S_addr = htonl(INADDR_ANY);			// 这个是any指的是不限制访问IP
//	char loa[16] = "192.168.15.189";						// 这是指定 IP发送数据 
//	sin.sin_addr.S_un.S_addr = inet_addr(loa);				// 加入指定 IP //	初始化slisten,加载上面代码设置的属性。if (bind(slisten, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR)	// 把sin强制类型转换为sockadd,sin原来是sockaddr_in类型{printf("bind error !");}//开始监听if (listen(slisten, 5) == SOCKET_ERROR){printf("listen error !");return 0;}
//	以上可以认为是建立服务器联系的固定格式//这里是多线程服务器,接受多个客户端,可以对比单线程看看多了什么,哪些函数的位置调整了sockaddr_in remoteAddr;int nAddrlen = sizeof(remoteAddr);while (true){printf("等待连接...\n");SOCKET sClient = accept(slisten, (SOCKADDR *)&remoteAddr, &nAddrlen);if (sClient == INVALID_SOCKET){printf("accept error !");}else{printf("接受到一个连接:%s \r\n", inet_ntoa(remoteAddr.sin_addr));if (clientHeadNote == NULL){clientHeadNote = addClient();clientEndNote = clientHeadNote;}
//			必须要先创建给end节点,然后再创建线程,因为线程的参数通过全局变量传入,而不是通过线程生成函数传入
//			原来线程参数除了 pthread_create()还能通过全局变量传参数hThread* clientnode = (hThread*)malloc(sizeof(hThread));								// 创建客户端结构体 clientnode->Client = sClient;clientnode->next = NULL;clientHeadNote->next = clientnode;clientEndNote = clientnode;clientnode->Thread = (pthread_t*)malloc(sizeof(pthread_t));								// 创建线程变量 clientnode->index = pthread_create(clientnode->Thread, NULL, ThreadClient, NULL);		// 创建线程并执行 }}printf("server is closing\n");hThread * p;while (clientHeadNote)  			 //释放占用的内存空间{p = clientHeadNote;clientHeadNote = clientHeadNote->next;delete p;}closesocket(slisten);WSACleanup();return 0;
}

这是单线程服务端 

#include <stdio.h>
#include <winsock2.h>
#include <conio.h>
#pragma comment(lib,"ws2_32.lib")
#pragma waring(disable :4996)
int main()
{WORD sockVersion = MAKEWORD(2,2);WSADATA wsaData;if(WSAStartup(sockVersion,&wsaData)!=0){printf("版本与结构体不匹配\n");return 0;}SOCKET slisten = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);if(slisten==INVALID_SOCKET){printf("socket error\n");return 0;}sockaddr_in sin;sin.sin_family = AF_INET;sin.sin_port = htons(8888);sin.sin_addr.S_un.S_addr = htonl(INADDR_ANY);if(bind(slisten,(LPSOCKADDR)&sin,sizeof(sin))==SOCKET_ERROR){printf("bind error\n");}if(listen(slisten,5)==SOCKET_ERROR){printf("listen error\n");return 0;}sockaddr_in remoteAddr;int nAddrlen=sizeof(remoteAddr);char rev[255];char sen[244];strcpy(sen,"okk\n");printf("等待连接\n");SOCKET sClient = accept(slisten,(SOCKADDR*)&remoteAddr,&nAddrlen);if(sClient==INVALID_SOCKET){printf("accpet error\n");}int ret=0;while(true){ret=0;ret =recv(sClient,rev,255,0);if(ret>0){printf("recieve\n");printf("ret = %d\n",ret);printf("消息为:%s\n",rev);send(sClient,sen,255,0);			// 0 代表阻塞发送,缓存起来,按顺序一个一个发strcpy(rev,"");						// 清空旧数据 }Sleep(100);}
}

这是客户端

#include <winsock2.h>
#include <stdio.h>
#include <pthread.h>
#pragma  comment(lib,"ws2_32.lib")
#pragma warning(disable : 4996)	
//格式和服务端一样
int main(int argc, char* argv[])
{WORD sockVersion = MAKEWORD(2, 2);WSADATA data;if (WSAStartup(sockVersion, &data) != 0){return 0;}SOCKET sclient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (sclient == INVALID_SOCKET){printf("无效的 socket !");return 0;}sockaddr_in serAddr;serAddr.sin_family = AF_INET;	// 表示使用IPv4地址协议 https://blog.csdn.net/u012736362/article/details/130392547serAddr.sin_port = htons(8888);char loa[16] = "127.0.0.1";		// 对方IP地址。当服务器的电脑的IP , win建+r 输入cmd,打开命令行,输入再直接 ipconfig/all可查看IP。serAddr.sin_addr.S_un.S_addr = inet_addr(loa);// IP是读取目标机器的IP,由于一台电脑当服务器和客户端,127.0.0.1是自回路,自己发送给自己//链接发消息while(connect(sclient, (sockaddr *)&serAddr, sizeof(serAddr)) == SOCKET_ERROR){//主动连接服务器printf("连接错误 !\n");Sleep(1000);}puts("连接成功!!");puts("你现在可以向服务器发送信息:");char sendData[100];char recData[255];while (1){scanf("%s",sendData);send(sclient, sendData, strlen(sendData), 0);		// 发送消息 0 代表阻塞 1 代表不阻塞 int ret = recv(sclient, recData, 255, 0);			// 接收消息 0 代表不执行这句,下面的都不执行 if (ret > 0){printf(recData);}}closesocket(sclient);WSACleanup();return 0;
}

 

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

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

相关文章

Springboot-接入WebSocket服务

1、依赖引入 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dependency> 2、启动类添加bean public class Application {/*** 会自动注册使用了ServerEndpoint注…

VMwareWorkstation17.0虚拟机安装Windows2.03完整详细步骤图文教程

VMwareWorkstation17.0虚拟机安装Windows2.03完整详细步骤图文教程 第一篇 下载Windows2.03第二篇 配置Windows2.03虚拟机机器环境第三篇 启动Windows2.03系统 第一篇 下载Windows2.03 1.Windows2.0原版软盘下载地址是 暂不提供&#xff0c;后续更新 2.Windows2.03虚拟机镜像下…

重案组第一季的观后感

继续研究美剧&#xff0c;重案组这部剧的人员组成&#xff0c;个性&#xff0c;特长&#xff0c;很有意思。 年龄&#xff0c;老中青三代。种族&#xff0c;白&#xff0c;黄&#xff0c;黑&#xff0c;有色。颜值&#xff0c;大众脸&#xff0c;很普通。对白&#xff0c;围绕…

鸿蒙开发-HarmonyOS UI架构

初步布局Index 当我们新建一个工程之后&#xff0c;首先会进入Index页。我们先简单的做一个文章列表的显示 class Article {title?: stringdesc?: stringlink?: string }Entry Component struct Index {State articles: Article[] []build() {Row() {Scroll() {Column() …

GiantPandaCV | 视觉类表面缺陷检测项目相关技术总结

本文来源公众号“GiantPandaCV”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;视觉类表面缺陷检测项目相关技术总结 本文由海滨撰写&#xff0c;首发于GaintPandaCV。 零、前言 做这个方向的项目也有一段时间了&#xff0c;作为…

Deep learning学习笔记

lec 1&#xff1a;Regression 1.5 Linear neural networks for regression线性神经网络的回归 I parameterizing output layer, I handling data, I specifying loss function, I training model. 浅层网络包括线性模型&#xff0c;其中包含了许多经典的统计预测方法&…

C++中的拷贝构造函数

一、拷贝构造函数的概念 拷贝构造函数用于创建一个与已有对象相同的对象&#xff0c;本质上也是构造函数的重载 拷贝构造函数只有一个类型为 const 类类型引用的形参&#xff0c;当我们要创建一个与已存在对象相同的对象时&#xff0c;由编译器自动调用拷贝构造函数。 clas…

简单的edge浏览器插件开发记录

今天在浏览某些网页的时候&#xff0c;我想要屏蔽掉某些信息或者修改网页中的文本的颜色、背景等等。于是在浏览器的控制台中直接输入JavaScript操作dom完成了我想要的功能。但是每次在网页之间跳转该功能都会消失&#xff0c;我需要反复复制粘贴js脚本&#xff0c;无法实现自动…

MATLAB知识点:exprnd函数(★★☆☆☆)生成指数分布的随机数

讲解视频&#xff1a;可以在bilibili搜索《MATLAB教程新手入门篇——数学建模清风主讲》。​ MATLAB教程新手入门篇&#xff08;数学建模清风主讲&#xff0c;适合零基础同学观看&#xff09;_哔哩哔哩_bilibili 节选自第3章&#xff1a;课后习题讲解中拓展的函数 在讲解第三…

【革新你的社交形象】用AI创意头像应用,让你的头像独一无二!

在这个数字化时代&#xff0c;社交媒体已经成为我们生活中不可或缺的一部分。你是否曾经为了找到一个既能表达自己个性&#xff0c;又足够吸引眼球的头像而苦恼&#xff1f;现在&#xff0c;有了我们全新推出的AI创意头像应用&#xff0c;你的这一困扰将成为过去&#xff01; …

React入门到精通:掌握前端开发的必备技能!

介绍&#xff1a;React是一个由Facebook开发和维护的JavaScript库&#xff0c;用于构建用户界面&#xff0c;特别是用于构建单页应用程序和移动应用程序的用户界面。以下是对React的详细介绍&#xff1a; 虚拟DOM&#xff1a;React通过使用虚拟DOM&#xff08;Document Object …

C++的进阶泛型编程学习(2):类模板的机制

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、类模板二、类模板和函数模板的区别1.类模板没有自动类型推导的方式2.类模板在模板参数列表中可以有默认参数 三、类模板对象做函数参数四、类模板与继承4.1…

【Deep Learning 2】神经网络的优化

&#x1f31e;欢迎来到PyTorch的世界 &#x1f308;博客主页&#xff1a;卿云阁 &#x1f48c;欢迎关注&#x1f389;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; &#x1f31f;本文由卿云阁原创&#xff01; &#x1f4c6;首发时间&#xff1a;&#x1f339;2024年2月16日&a…

平滑几何名词

G0: Position (touching) G1: Tangent (angle) G2: Curvature (radius) G3&#xff1a; A G3 path is characterized by a continuously differentiable curvature profile。Acceleration/Torsion (rate of change of curvature 、 sharpness) clothoid: An Euler spi…

2.16C语言学习

P1296 奶牛的耳语 一开始以为是普通的二重循环&#xff0c;结果做出来答案是错的&#xff0c;但是思路不可能有问题&#xff0c;于是抱着试一试的想法加了一个排序&#xff0c;这样就过了&#xff0c;每次在第二重循环里遇到大于最小能听到的距离就跳出循环&#xff0c;进入下…

java8-重构、测试、调试

8.1.1 改善代码的可读性 改善代码的可读性到底意味着什么?我们很难定义什么是好的可读性&#xff0c;因为这可能非常主观。通常的理解是&#xff0c;“别人理解这段代码的难易程度”。改善可读性意味着你要确保你的代码能非常容易地被包括自己在内的所有人理解和维护。为了确保…

在Spring中事务失效的场景

在Spring框架中&#xff0c;事务管理是通过AOP&#xff08;面向切面编程&#xff09;实现的&#xff0c;主要依赖于Transactional注解。然而&#xff0c;在某些情况下&#xff0c;事务可能会失效。以下是一些可能导致Spring事务失效的常见场景&#xff1a; 非public方法&#…

2月16日,每日信息差

第一、2024春节档总观影人次进入影史前二&#xff0c;截至2月16日16时31分&#xff0c;2024年春节档总观影人次达1.46亿&#xff08;含预售&#xff09;&#xff0c;超2018年春节档总观影人次1.45亿&#xff0c;成为中国影史春节档总观影人次第二名。《热辣滚烫》《飞驰人生2》…

阿里云“BGP(多线)”和“BGP(多线)_精品”区别价格对比

阿里云香港等地域服务器的网络线路类型可以选择BGP&#xff08;多线&#xff09;和 BGP&#xff08;多线&#xff09;精品&#xff0c;普通的BGP多线和精品有什么区别&#xff1f;BGP&#xff08;多线&#xff09;适用于香港本地、香港和海外之间的互联网访问。使用BGP&#xf…

悦纳自己:拥抱个人局限,开启成长之旅

悦纳自己&#xff1a;拥抱个人局限&#xff0c;开启成长之旅 在人生的旅途中&#xff0c;我们每个人都会面临无数的挑战和选择。有时我们会因为这些挑战而感到焦虑和不安&#xff0c;因为我们害怕失败&#xff0c;害怕无法达到预期的目标。然而&#xff0c;真正重要的是我们如何…