原文为单工通信,但时间太久找不到了,后为我修改成为双工,原作者看到私聊我!

当时在把单工变成双工时总是在琢磨怎么边收边发,后来好朋友指点多线程+教学+查资料才学会,与单工通信相比,增加线程即可。

效果如下:

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语言相关推荐

  1. c语言socket+全双工,用Winsock实现语音全双工通信使用

    二.主要函数的使用要点 通过建立双套接字,可以很方便地实现全双工网络通信. 1.套接字建立函数: SOCKET socket(int family,int type,int protocol) ...

  2. Linux-C语言-利用有名管道简单实现两个进程间的全双工通信

    有名管道特点: 1.有名管道是对无名管道的改进,它可以使互不相关的两个进程互相通信,并且在文件系统中可见,可以通过文件名来找到. 2.半双工的通信方式,进程通过文件IO来操作有名管道. 3.有名管道遵 ...

  3. web技术_使用浏览器进行全双工通信的 WebSocketHTTP协议的性能瓶颈AjaxCometSPDY技术

    文章目录 使用浏览器进行全双工通信的 WebSocket&HTTP协议的性能瓶颈&Ajax&Comet&SPDY技术 http的性能问题 Ajax 的解决方法 Ajax ...

  4. 单工通信、半双工通信和全双工通信的区别

    对于点对点之间的通信,按照消息传送的方向与时间关系,通信方式可分为单工通信.半双工通信及全双工通信三种. 一.单工通信 单工通信(Simplex Communication)是指消息只能单方向传输的工 ...

  5. 半双工通信和全双工通信的区别

    半双工通信和全双工通信的区别 对于点对点之间的通信,按照消息传送的方向与时间关系,通信方式可分为单工通信.半双工通信及全双工通信三种. 单工通信 单工通信(Simplex Communication) ...

  6. 单工通信模式、半双工通信模式和全双工通信模式的区别

    计算机的通信方式 了解计算机的通信方式,可以更好的帮助我们理解网络是如何交互的,我们知道计算机的两种基本通信方式是串行通信和并行通信. 串行通信指在计算机总线或其他数据通百道上,每次传输一个位元数据, ...

  7. 单工通信、半双工通信、全双工通信 的概念

    ps: 如果有任何问题可以评论留言,我看到后会及时解答,评论或关注,您的鼓励是我分享的最大动力 转载请注明出处:https://blog.csdn.net/qq_40938301/article/de ...

  8. java socket 全双工客户端_java socket实现全双工通信

    单工.半双工和全双工的定义 如果在通信过程的任意时刻,信息只能由一方A传到另一方B,则称为单工. 如果在任意时刻,信息既可由A传到B,又能由B传A,但只能由一个方向上的传输存在,称为半双工传输. 如果 ...

  9. zeroc-ice的全双工通信策略

    在项目中,往往很多时候涉及全双工通信要求,zeroc-ice样例介绍很多异步通信的策略, 但我最近项目需求中,不仅是要全双工通信,还要求服务端需要明确每个客户端及区别对待, 所以需要给每个客户端做标记 ...

最新文章

  1. Anaconda简单入门
  2. Mysql(3)——mysql数据类型
  3. leetcode 1723. 完成所有工作的最短时间(二分+剪枝+回溯)
  4. 第九十三期:带你聊聊 Java 并发编程之线程基础
  5. NB模组基本AT指令
  6. 亚信安全发布《2022年网络安全发展趋势及十大威胁预测》
  7. linux终端 打开光驱,ubuntu如何挂载光盘? Ubuntu下中手动挂载光盘的教程
  8. java路径通配符_java实现路径通配符*,**,?
  9. 人人网是明文传输,所以只要抓包就能知道用户名和密码
  10. Unrecognized Windows Sockets error: 10106的解决办法
  11. Element修改图标大小,设置颜色
  12. 一个最简单的自定义锁屏应用实现
  13. 微信小程序:高德地图搜索周边poi接口实践
  14. 字体反扒 ---汽车之家(文字)
  15. windows 组策略
  16. 新团队团队融合研讨会_行程报告:2020年软件开发人员多样性与融合研讨会
  17. R: 更改行名及矩阵数据提取的易错点——下标出界
  18. java项目-第71期基于ssm的化妆品商城系统【毕业设计】
  19. VB,VC,Delphi,SDK笑话
  20. 人生总在不断的折腾,你不折腾,就要被折腾......

热门文章

  1. 图对比学习 GMI code study
  2. 设计驱动儿童教育应用——“斑马骑士”创始人徐毅斐专访
  3. 自媒体视频怎么做?做过的一些经验
  4. 人类蛋白免疫组化表达数据库使用指南
  5. 如何重新在奥维地图恢复谷歌地图
  6. 汽车零部件制造业-MES调研报告要点及思路
  7. OCP最成功的项目是什么?许多数据中心硬件从业者都会和它打交道
  8. ucloud UDataArk 测试
  9. python简笔画_用Python画个万圣节南瓜怪
  10. Atlas 200 DK 系列--初级篇--MindStudio常见操作