网络编程学习笔记一 第一个服务器端程序
来源:互联网 发布:淘宝如何优化宝贝标题 编辑:程序博客网 时间:2024/04/29 17:50
在坎坷路途中的第一个服务器端程序
能注释的地方我都注释了,因为才学2天,大家如果看到有什么地方有问题的请帮忙指出来。
// T2Server.cpp : 定义控制台应用程序的入口点。//#include<iostream>#include<WinSock2.h>#pragma comment(lib,"WS2_32")using namespace std;#define REQUEST_BACKLOG 5//如果想要使用SOCKET,WSAStartup函数必须要进行初始化才可以bool initWSA(const WORD &wVersion ,WSADATA *wsadata){int Ret = 0;if(Ret = WSAStartup(wVersion,wsadata)!=0){cout<<"WSAStartup Error "<<Ret<<endl;return FALSE;}return true;}void cleanWSA(){if(WSACleanup() == SOCKET_ERROR){cout<<"WSACleanup failed ,error"<<WSAGetLastError()<<endl;}}//这个是初始化服务器地址,包括IP地址和端口void InitSockAddrByIP(SOCKADDR_IN *pSockAddr ,const char FAR*strIP,const INT &nPortID){pSockAddr->sin_family = AF_INET;//htons这个不能忘了,网络字节序必须要转换,不然经常会出大问题pSockAddr->sin_port = htons(nPortID);if(0!=strlen(strIP)){pSockAddr->sin_addr.S_un.S_addr = inet_addr(strIP); // pSockAddr->sin_addr.S_un.S_addr = htonl(INADDR_ANY);cout<<inet_ntoa(pSockAddr->sin_addr)<<endl; //pSockAddr->sin_addr.s_addr = inet_addr(strIP); // pSockAddr->sin_addr.s_addr =htonl(inet_addr(strIP));}else{pSockAddr->sin_addr.S_un.S_addr =htonl(INADDR_ANY);}}//将端口地址对象和sock对象进行绑定,也就是和后文的sock_listen对象bool bindAddr(const SOCKADDR_IN * pSockAddr ,SOCKET pSocket){int bindResult = bind(pSocket,(sockaddr*)(pSockAddr),sizeof(SOCKADDR_IN));if(SOCKET_ERROR == bindResult){cout<<"bind error : "<<WSAGetLastError()<<endl;return false;}elsereturn true;}//这个是创建监听器,一旦有连接请求和发送信息的请求我们就能接收到了bool SetListen(SOCKET s,int backlog){int ListenResult = listen(s,backlog);if(SOCKET_ERROR == ListenResult){cout<<"listen error"<<WSAGetLastError()<<endl;return false;}elsereturn true;}int main(){WSADATA wsadata;if(!initWSA(MAKEWORD(2,2),&wsadata)){return 0;}//指定连接IP地址和服务器端口 SOCKADDR_IN internetAddr;memset(&internetAddr, 0, sizeof(struct sockaddr_in));char FAR *strIP ="192.168.1.101";//这个是服务器的IP地址INT nPortID = 5150;InitSockAddrByIP(&internetAddr,strIP,nPortID);//创建listener_socketSOCKET listener_socket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);if(INVALID_SOCKET ==listener_socket){cout<<"listener_socket creat failed"<<endl;return 0;}if(!bindAddr(&internetAddr,listener_socket))return 0; if (!SetListen(listener_socket, REQUEST_BACKLOG ) ) { return 0; } cout<<"server started ~~~"<<endl;//创建socket保存结构fd_set fdSocket;FD_ZERO(&fdSocket);FD_SET(listener_socket,&fdSocket);//查找可读的socketwhile(1){//这个只是一个缓冲对象fd_set fdSocket_temp; FD_ZERO(&fdSocket_temp);fdSocket_temp = fdSocket;//这个是读用的fd_set fdRead;FD_ZERO(&fdRead);fdRead = fdSocket;//这个是catch错误用的fd_set fdExceptds;FD_ZERO(&fdExceptds);fdExceptds = fdSocket;//除了第一个参数,第二个参数是读fd_set对象,第三个参数是写fd_set对象,第四个参数是catch错误的fd_set对象int nResult_select = select(0,&fdRead,NULL,&fdExceptds,NULL);//这个时候表示有消息了if(0 <nResult_select){int socket_count = fdSocket_temp.fd_count;for(int i =0;i<socket_count;i++){//如果现在fdRead里有消息传来if(FD_ISSET(fdSocket_temp.fd_array[i],&fdRead)){if(fdSocket_temp.fd_array[i]==listener_socket)//如果是当前正在监听的表示这个还未接受连接,那我们就接下来连接就好了,其他的已经连接上的就接收信息就好了{if(fdSocket.fd_count<FD_SETSIZE){//接受这个新的连接SOCKADDR_IN ClientAddr;int addrlen = static_cast<int>(sizeof(ClientAddr)); //一定要赋值 SOCKET newClient_SOCKET = accept(listener_socket,(sockaddr *)&ClientAddr,&addrlen); cout<<inet_ntoa(ClientAddr.sin_addr)<<endl;if(INVALID_SOCKET==newClient_SOCKET){cout<<"accep error "<<WSAGetLastError()<<endl;}else{FD_SET(newClient_SOCKET,&fdSocket);cout<<"add new connect"<<endl;}}else{cout<<"too much connecttion"<<endl;}}//已经连接上了的我们就直接接收数据好了else{char recvbuff[1024];int ret = 0;ret = recv(fdSocket_temp.fd_array[i],recvbuff,static_cast<int>(strlen(recvbuff)),0);if(ret>0){recvbuff[ret]='\0';cout<<"recv: "<<recvbuff<<endl;//回复给客户端char backbuf[1024]="recevie OK";send( fdSocket_temp.fd_array[i], backbuf, static_cast<int>( strlen(backbuf) ), 0 ); }else //此时ret返回值为0{//连接已经断开了。断开有很短原因closesocket(fdSocket_temp.fd_array[i]);//在fd_set中去掉这个连接FD_CLR(fdSocket_temp.fd_array[i],&fdSocket );}}}//既然没有发送消息又占用了连接的位置,我们就释放他来控制空闲的空间else if(fdSocket_temp.fd_array[i] != listener_socket ){ //该连接断开 closesocket( fdSocket_temp.fd_array[i] ); FD_CLR( fdSocket_temp.fd_array[i], &fdSocket ); }//如果Catch到了错误if(FD_ISSET(fdSocket_temp.fd_array[i],&fdExceptds)&& (fdSocket_temp.fd_array[i] != listener_socket) ) { //该连接断开 closesocket( fdSocket_temp.fd_array[i] ); FD_CLR( fdSocket_temp.fd_array[i], &fdSocket ); }}} else if( SOCKET_ERROR ==nResult_select ) { cout << "select error : " << WSAGetLastError() << endl; return 0; } Sleep(50);//这个必须要,不然死循环一直弄下去机子可能会死去。。}closesocket(listener_socket);cleanWSA();return 0;}
- 网络编程学习笔记一 第一个服务器端程序
- C#高级编程 学习笔记(一) 第一个C#程序
- DirectShow 学习笔记< 一> -- 第一个程序
- 网络编程:第一个网络程序
- 网络编程学习笔记二 第一个客户端主程序
- TCP/IP高效编程-改善网络程序的44个技巧学习笔记(一)
- 网络编程学习笔记(服务器端进程终止)
- struts2 学习笔记一 第一个struts2程序
- NHibernate3学习笔记(一)--第一个NHibernate程序
- android学习笔记(一):第一个android程序
- opencv学习笔记(一) 配置环境、第一个程序
- opengl学习笔记一之第一个程序
- OC学习笔记一---第一个OC程序
- Spring学习笔记(一)第一个Spring程序
- 《Hibernate学习笔记一》:第一个程序的搭建
- C++学习笔记一:第一个C++程序“hello worl
- 《Hibernate学习笔记一》第一个程序的搭建
- 《UNIX网络编程(卷一)》第一至六章学习笔记
- 视频码率,帧率和分辨率及H264介绍
- Navigation Drawer介绍
- hdu 1008 Elevator
- Mongodb的备份与恢复
- Mac OS的java版本问题和Eclipse中无法找到jdk源代码的问题解决办法
- 网络编程学习笔记一 第一个服务器端程序
- linux如何查看系统信息
- URAL 1029
- ListView效果优化
- 数据结构与程序设计第一章总结
- 程序原理
- 关于深度优先搜索和广度优先搜索C语言的简明实现
- UVa 127 手风琴纸牌 “Accordian“Patience
- fluentd 插件开发