计算机网络winsock全双工通信C语言
原文为单工通信,但时间太久找不到了,后为我修改成为双工,原作者看到私聊我!
当时在把单工变成双工时总是在琢磨怎么边收边发,后来好朋友指点多线程+教学+查资料才学会,与单工通信相比,增加线程即可。
效果如下:
sever.cpp
#include<stdio.h>
#include<winsock.h>
#include<pthread.h>//=======================定义变量=======================//char sendBuffer[100]; //发送数据的缓冲区char receiveBuffer[100]; //接收数据的缓冲区int sendLength; //发送数据的长度int receiveLength; //接收数据的长度int length; //表示SOCKADDR的大小SOCKET socketServer; //服务器套接字SOCKET socketClient; //客户端的连接套接字SOCKADDR_IN serverAddress; //服务器地址SOCKADDR_IN clientAddress; //客户端地址WORD wVersonRequested; //字(word):unsigned shortWSADATA wsaData; //库版本信息结构int error; //表示错误
//=======================发送数据=======================//
void* sendMessage(void *a){while(1){ if(gets(sendBuffer)==""){} else{//printf("我:");//scanf("%s",sendBuffer);
先比较待发送数据的长度len和套接字s的发送缓冲区的长度,如果len大于s的发送缓冲区的长度,该函数返回SOCKET_ERROR
如果len小于或等于s的发送缓冲区的长度,sendLength=send(socketClient,sendBuffer,100,0); if(sendLength<0){printf("-(发送失败!)\n");}else{printf("-(发送成功!)\n"); }}}}
//=======================接收数据=======================//
void* reciveMessage(void *b){while(1){receiveLength=recv(socketClient,receiveBuffer,100,0);if(receiveLength<0){printf("(接收失败!)\n");printf("(程序退出!)\n");break;}else{printf("对方消息: %s\n",receiveBuffer); //显示客户端发送的数据 }}
}int main()
{//====================初始化套接字库====================//wVersonRequested=MAKEWORD(2,2); //定义版本类型,将两个字节组合成一个字,前面是低字节,后面是高字节error=WSAStartup(wVersonRequested,&wsaData); //加载套接字库,初始化ws2_32.dll动态链接库 if(error!=0){printf("加载套接字库失败!\n");return 0; //程序结束 }if(LOBYTE(wsaData.wVersion)!=2||HIBYTE(wsaData.wVersion)!=2)//判断版本号是否和定义的一样 {WSACleanup(); //不符合 支持卸载 return 0; //程序结束 }//=====================设置连接地址=====================//serverAddress.sin_family=AF_INET; //地址家族,对于必须是AF_INET,注意只有它不是网络字节顺序serverAddress.sin_addr.S_un.S_addr=htonl(INADDR_ANY); //IP地址,主机地址,INADDR_ANY即为inet_addr("0.0.0.0"),//让服务器端计算机上的所有网卡的IP地址都可以作为服务器IP地址serverAddress.sin_port=htons(5050); //端口号//===================创建服务器套接字===================// socketServer=socket(AF_INET,SOCK_STREAM,0); //AF_INET表示地址族,SOCK_STREAM表示流式套接字TCP,特定的地址家族相关的协议//描述符 //===========绑定套接字到本地某个地址和端口上===========// /*socketServer为套接字,(SOCKADDR*)&serverAddress为服务器地址,sizeof(SOCKADDR))==SOCKET_ERROR地址的长度*/ //成功返回0 if(bind(socketServer,(SOCKADDR*)&serverAddress,sizeof(SOCKADDR))==SOCKET_ERROR){printf("绑定失败!\n");}else{printf("绑定成功地址端口!\n"); } //=================设置套接字为监听状态=================// if(listen(socketServer,10)<0) //监听状态,为连接做准备,等待队列的最大长度 {printf("监听失败!\n"); }else{printf("正在监听...\n"); } //=======================接收连接=======================//length=sizeof(SOCKADDR);/*接收客户端的发送请求,等待客户端的连接请求*/socketClient=accept(socketServer,(SOCKADDR*) &clientAddress,&length);if(socketClient==SOCKET_ERROR){printf("接收连接失败!\n");}//=======================创建两个线程=======================//pthread_t t0;pthread_t t1;// 创建线程A sendMessage() if(pthread_create(&t0, NULL,sendMessage, NULL) == -1){puts("fail to create pthread t0");exit(1);}//创建线程B reciveMessage() if(pthread_create(&t1, NULL,reciveMessage, NULL) == -1){puts("fail to create pthread t1");exit(1);}// 等待线程结束void * result;if(pthread_join(t0, &result) == -1){puts("fail to recollect t0");exit(1);}if(pthread_join(t1, &result) == -1){puts("fail to recollect t1");exit(1);}//=======================进行聊天=======================////==============释放套接字,关闭动态库==============//closesocket(socketClient); //关闭客户端的套接字资源 closesocket(socketServer); //关闭服务器的套接字资源 WSACleanup(); //关闭动态链接库 return 0;
}
client.cpp
#include<stdio.h>
#include<winsock.h>
#include<pthread.h>//=======================定义变量=======================//char sendBuffer[100]; //发送数据的缓冲区char receiveBuffer[100]; //接收数据的缓冲区int sendLength; //发送数据的长度int receiveLength; //接收数据的长度SOCKET socketClient; //客户端的连接套接字SOCKADDR_IN serverAddress; //服务器地址信息结构WORD wVersonRequested; //字(word):unsigned shortWSADATA wsaData; //库版本信息结构int error; //表示错误
//=======================发送数据=======================//
void* sendMessage(void *a){ while(1){//printf("我:");if(gets(sendBuffer)==""){} // scanf("%s",sendBuffer);
先比较待发送数据的长度len和套接字s的发送缓冲区的长度,如果len大于s的发送缓冲区的长度,该函数返回SOCKET_ERROR
如果len小于或等于s的发送缓冲区的长度,else{sendLength=send(socketClient,sendBuffer,100,0); //发送数据: if(sendLength<0) {printf("-(发送失败!)\n"); } else{printf("-(发送成功!)\n"); }}}}
//=======================接受数据=======================//
void* reciveMessage(void *b){while(1){recv先等待s的发送缓冲中的数据被协议传送完毕,如果协议在传送s的发送缓冲中的数据时出现网络错误,那么recv函数返回SOCKET_ERROR,
如果s的发送缓冲中没有数据或数据被协议成功发送完毕后, receiveLength=recv(socketClient,receiveBuffer,100,0);if(receiveLength<0){printf("(接收失败!)\n");printf("(程序结束!)\n");break;}else{printf("对方消息:%s\n",receiveBuffer);}}
}int main()
{//====================初始化套接字库====================//wVersonRequested=MAKEWORD(2,2); //定义版本类型,将两个字节组合成一个字,前面是低字节,后面是高字节error=WSAStartup(wVersonRequested,&wsaData); //加载套接字库,初始化ws2_32.dll动态链接库 if(error!=0){printf("加载套接字库失败!\n");return 0; //程序结束 }if(LOBYTE(wsaData.wVersion)!=2||HIBYTE(wsaData.wVersion)!=2)//判断版本是否与定义的一样 {WSACleanup(); //不符合 支持卸载 return 0; //程序结束 }//=====================设置连接地址=====================//serverAddress.sin_family=AF_INET; //地址家族,对于必须是AF_INET,注意只有它不是网络字节顺序serverAddress.sin_addr.S_un.S_addr=inet_addr("127.0.0.1"); //主机地址serverAddress.sin_port=htons(5050); //端口号 //=====================连接到服务器=====================//socketClient=socket(AF_INET,SOCK_STREAM,0); //客户端创建套接字,但是不需要绑定,只需要和服务端建立连接就可以了/*进行连接服务器*/if(connect(socketClient,(SOCKADDR*)&serverAddress,sizeof(SOCKADDR))==SOCKET_ERROR){printf("连接失败!\n"); return -1;} else{printf("连接成功!\n");}//=======================创建两个线程=======================//pthread_t t0;pthread_t t1;// 创建线程A sendMessage() if(pthread_create(&t0, NULL,sendMessage, NULL) == -1){puts("fail to create pthread t0");exit(1);}//创建线程B reciveMessage() if(pthread_create(&t1, NULL,reciveMessage, NULL) == -1){puts("fail to create pthread t1");exit(1);}// 等待线程结束void * result;if(pthread_join(t0, &result) == -1){puts("fail to recollect t0");exit(1);}if(pthread_join(t1, &result) == -1){puts("fail to recollect t1");exit(1);}//==============释放套接字,关闭动态库==============//closesocket(socketClient); //关闭客户端的套接字资源 WSACleanup(); //关闭动态链接库 return 0;
}
计算机网络winsock全双工通信C语言相关推荐
- c语言socket+全双工,用Winsock实现语音全双工通信使用
二.主要函数的使用要点 通过建立双套接字,可以很方便地实现全双工网络通信. 1.套接字建立函数: SOCKET socket(int family,int type,int protocol) ...
- Linux-C语言-利用有名管道简单实现两个进程间的全双工通信
有名管道特点: 1.有名管道是对无名管道的改进,它可以使互不相关的两个进程互相通信,并且在文件系统中可见,可以通过文件名来找到. 2.半双工的通信方式,进程通过文件IO来操作有名管道. 3.有名管道遵 ...
- web技术_使用浏览器进行全双工通信的 WebSocketHTTP协议的性能瓶颈AjaxCometSPDY技术
文章目录 使用浏览器进行全双工通信的 WebSocket&HTTP协议的性能瓶颈&Ajax&Comet&SPDY技术 http的性能问题 Ajax 的解决方法 Ajax ...
- 单工通信、半双工通信和全双工通信的区别
对于点对点之间的通信,按照消息传送的方向与时间关系,通信方式可分为单工通信.半双工通信及全双工通信三种. 一.单工通信 单工通信(Simplex Communication)是指消息只能单方向传输的工 ...
- 半双工通信和全双工通信的区别
半双工通信和全双工通信的区别 对于点对点之间的通信,按照消息传送的方向与时间关系,通信方式可分为单工通信.半双工通信及全双工通信三种. 单工通信 单工通信(Simplex Communication) ...
- 单工通信模式、半双工通信模式和全双工通信模式的区别
计算机的通信方式 了解计算机的通信方式,可以更好的帮助我们理解网络是如何交互的,我们知道计算机的两种基本通信方式是串行通信和并行通信. 串行通信指在计算机总线或其他数据通百道上,每次传输一个位元数据, ...
- 单工通信、半双工通信、全双工通信 的概念
ps: 如果有任何问题可以评论留言,我看到后会及时解答,评论或关注,您的鼓励是我分享的最大动力 转载请注明出处:https://blog.csdn.net/qq_40938301/article/de ...
- java socket 全双工客户端_java socket实现全双工通信
单工.半双工和全双工的定义 如果在通信过程的任意时刻,信息只能由一方A传到另一方B,则称为单工. 如果在任意时刻,信息既可由A传到B,又能由B传A,但只能由一个方向上的传输存在,称为半双工传输. 如果 ...
- zeroc-ice的全双工通信策略
在项目中,往往很多时候涉及全双工通信要求,zeroc-ice样例介绍很多异步通信的策略, 但我最近项目需求中,不仅是要全双工通信,还要求服务端需要明确每个客户端及区别对待, 所以需要给每个客户端做标记 ...
最新文章
- Anaconda简单入门
- Mysql(3)——mysql数据类型
- leetcode 1723. 完成所有工作的最短时间(二分+剪枝+回溯)
- 第九十三期:带你聊聊 Java 并发编程之线程基础
- NB模组基本AT指令
- 亚信安全发布《2022年网络安全发展趋势及十大威胁预测》
- linux终端 打开光驱,ubuntu如何挂载光盘? Ubuntu下中手动挂载光盘的教程
- java路径通配符_java实现路径通配符*,**,?
- 人人网是明文传输,所以只要抓包就能知道用户名和密码
- Unrecognized Windows Sockets error: 10106的解决办法
- Element修改图标大小,设置颜色
- 一个最简单的自定义锁屏应用实现
- 微信小程序:高德地图搜索周边poi接口实践
- 字体反扒 ---汽车之家(文字)
- windows 组策略
- 新团队团队融合研讨会_行程报告:2020年软件开发人员多样性与融合研讨会
- R: 更改行名及矩阵数据提取的易错点——下标出界
- java项目-第71期基于ssm的化妆品商城系统【毕业设计】
- VB,VC,Delphi,SDK笑话
- 人生总在不断的折腾,你不折腾,就要被折腾......