C++ 网络编程 阻塞I/O模型并发回显服务器
来源:互联网 发布:致远软件招聘 编辑:程序博客网 时间:2024/05/22 12:22
#include<iostream>#include<WinSock2.h>using namespace std;#pragma comment(lib,"Ws2_32.lib")const int nPort=10000;const int nDefaultBufferSize=1024;DWORD WINAPI ThreadProc(LPVOID lpParama){ SOCKET sd=(SOCKET)lpParama; char buff[nDefaultBufferSize]; int nRecv; do{ //循环直到客户端关闭数据连接 nRecv=recv(sd,buff,nDefaultBufferSize,0); //返回的是接收到的字节数,若为0表示客户端断绝连接 if(nRecv==SOCKET_ERROR) {//判断接收是否出现异常 cout<<"接收异常"<<WSAGetLastError()<<endl; return -1; } else if(nRecv>0) { int nSent=0; //将数据原封不动的发回去 while(nSent<nRecv) { int nTemp=send(sd,&buff[nSent],nRecv-nSent,0); if(nTemp>0) //正常发送情况 { //说明发送出nTemp个字节数据 nSent+=nTemp;//表明到目前为止已发送nSent个字节数据 } else if(nTemp==SOCKET_ERROR)//发送异常情况 { cout<<"发送出错"<<WSAGetLastError()<<endl; return -1; } else //send返回0,表示客户端意外关闭,没有发送完所有的数据客户端就关闭了 { cout<<"客户端关闭"<<WSAGetLastError()<<endl; } } } }while(nRecv!=0); cout<<"数据传输完毕,客户端断开连接"<<endl; //客户端关闭连接后,服务器需要进入第三阶段,即把当前客户端连接关闭 //首先发送一个FIN字段 if(shutdown(sd,SD_SEND)==SOCKET_ERROR) { cout<<"发送FIN字段失败"<<WSAGetLastError()<<endl; return -1; } char buff1[nDefaultBufferSize]; int nRecv1; //继续接受对方的数据直到recv返回0为止 do{ nRecv1=recv(sd,buff1,nDefaultBufferSize,0); if(nRecv1==SOCKET_ERROR) { cout<<"接收异常"<<WSAGetLastError()<<endl; return -1; } else if(nRecv1>0) { cout<<"接收到不需要的数据"<<endl; } }while(nRecv1!=0); if(closesocket(sd)==SOCKET_ERROR) { cout<<"关闭异常"<<WSAGetLastError()<<endl; return -1; } return 0;}int main(){WSAData wsaData;int nCode;nCode=WSAStartup(MAKEWORD(2,2),&wsaData);//初始化Winsock库,MAKEWORD(2,2)表示Winsock2.2版本if(nCode!=0){cout<<"Winsock初始化失败"<<endl;return -1;}SOCKET sdListen=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);//创建一个套接字if(sdListen==INVALID_SOCKET){//判断创建套接字是否成功cout<<"创建失败"<<endl;return -1;}sockaddr_in sd; //创建本地套接字sd.sin_family=AF_INET; //表明使用的是IPv4;sd.sin_port=htons(nPort);//用于将主机16位无符号整数字节序转换成网络字节序sd.sin_addr.s_addr=htonl(INADDR_ANY);//用于将主机32为无符号整数字节序转换为网络字节序if(bind(sdListen,(sockaddr*)&sd,sizeof(sockaddr_in))==SOCKET_ERROR){//判断是否绑定成功cout<<"绑定失败"<<WSAGetLastError()<<endl;closesocket(sdListen);return -1;}if(listen(sdListen,5)==SOCKET_ERROR){//判断监听是否成功cout<<"监听失败"<<WSAGetLastError()<<endl;closesocket(sdListen);return -1;}while(true) //进入服务器主循环核心部分{sockaddr_in saClient;//用于保存客户端的地址信息int nSize=sizeof(sockaddr_in);//用于保存客户端地址信息的大小SOCKET sd=accept(sdListen,(sockaddr*)&saClient,&nSize);//从待处理客户连接请求队列中取出第一个,为//该连接请求创建一个新的套接字,并返回该套接字的句柄if(sd==INVALID_SOCKET){//如果此句柄无效,则突出循环break;}//创建一个新的线程来服务刚刚接受的客户端连接DWORD dwThreadId;HANDLE hThread=CreateThread(0,0,ThreadProc,(LPVOID)sd,0,&dwThreadId);CloseHandle(hThread);} if(closesocket(sdListen)==SOCKET_ERROR){cout<<"关闭总套接字失败"<<WSAGetLastError()<<endl;}WSACleanup();//释放资源return 0;}
0 0
- C++ 网络编程 阻塞I/O模型并发回显服务器
- 网络编程中阻塞与非阻塞,同步与异步、I/O模型的理解
- 【UNIX网络编程】五种I/O模型,阻塞非阻塞同步异步问题详解
- 网络编程中阻塞与非阻塞、同步与异步、I/O模型的理解
- 网络编程中阻塞与非阻塞,同步与异步、I/O模型的理解
- 网络编程中阻塞与非阻塞,同步与异步、I/O模型的理解
- 《网络编程》I/O 模型
- 网络编程 I/O模型
- 《网络编程》非阻塞 I/O
- 【Unix 网络编程】服务器网络编程模型——I/O复用:select 函数
- WIN网络编程-select(I/O模型)
- unix编程---网络I/O模型
- unix编程---网络I/O模型
- VC++网络编程 WINSOCK I/O模型
- Unix网络编程中的I/O模型
- UNIX网络编程 I/O模型
- unix网络编程-I/O模型
- [网络编程]_[Socket]_[Socket 阻塞模式(blocking)下的 I/O模型(model) 之 Select 模型(model)初探]
- ORACLE日期时间函数大全
- iOS雷达图 iOS RadarChart实现
- Java基于Socket文件传输示例
- quartz 定时任务的删除 恢复 已经暂停
- Spring MVC @Transactional注解方式事务失效的解决办法
- C++ 网络编程 阻塞I/O模型并发回显服务器
- mysql里的批处理(sql语句)、触发器、事务管理、存储过程
- Java工具类——实现静态图片剪切缩放功能
- mysql全文检索
- IP网际协议
- echarts选项卡切换效果,并且自适应随着窗口大小变大变小。
- 最简单的windows程序——MFC版本
- PHP 数据库 事务操作
- Base64