网络编程学习笔记一 第一个服务器端程序

来源:互联网 发布:淘宝如何优化宝贝标题 编辑:程序博客网 时间: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;}

 
	
				
		
原创粉丝点击