1 //Server.cpp 2 #include <stdio.h> 3 #include <winsock2.h> //winsock.h (2種套接字版本) 4 #pragma comment(lib,"ws2_32.lib") //wsock32.lib 5 6 #define MAXSIZE 100 // 7 8 int main() 9 { 10 // 11 int retVal; 12 13 char buf[MAXSIZE]; 14 15 //初始化套接字庫 16 WORD wVersionRequest; 17 WSADATA wsadata; 18 19 wVersionRequest=MAKEWORD(2,2); 20 21 retVal=WSAStartup(wVersionRequest,&wsadata); 22 if(retVal == SOCKET_ERROR) 23 { 24 printf("WSAStartup failed!"); 25 26 return -1; 27 } 28 29 //建立套接字 30 SOCKET sServer; 31 sServer=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); 32 if(sServer == INVALID_SOCKET) 33 { 34 printf("socket failed!"); 35 36 WSACleanup(); 37 return -1; //每次檢測到失敗後,即須要返回 38 } 39 40 //設置爲非阻塞模式 41 int imode=1; 42 retVal=ioctlsocket(sServer,FIONBIO,(u_long *)&imode); 43 if(retVal == SOCKET_ERROR) 44 { 45 printf("ioctlsocket failed!"); 46 47 closesocket(sServer); 48 WSACleanup(); 49 return -1; 50 } 51 52 //綁定套接字並將其設置爲監聽狀態 53 SOCKADDR_IN addrServ; 54 addrServ.sin_family=AF_INET; 55 addrServ.sin_port =htons(5000); 56 addrServ.sin_addr.S_un.S_addr=inet_addr("192.168.0.102"); 57 58 retVal=bind(sServer,(SOCKADDR *)&addrServ,sizeof(addrServ)); //綁定套接字到某一個具體的服務器 59 if(retVal == SOCKET_ERROR) 60 { 61 printf("bind failed!"); 62 63 closesocket(sServer); 64 WSACleanup(); 65 return -1; 66 } 67 68 retVal=listen(sServer,1); //第二個參數,表示最大鏈接數目 69 if(retVal == SOCKET_ERROR) 70 { 71 printf("listen failed!"); 72 73 closesocket(sServer); 74 WSACleanup(); 75 return -1; 76 } 77 78 79 //接受鏈接 80 sockaddr_in addrClient; //定義一個臨時地址,用於接受鏈接(注意:某個客戶端由Client.cpp肯定) 81 int len=sizeof(sockaddr_in); 82 83 SOCKET sClient; 84 int errcode; 85 86 while(true) 87 { 88 sClient=accept(sServer,(sockaddr *)&addrClient,&len); 89 if(sClient == INVALID_SOCKET) 90 { 91 errcode=WSAGetLastError(); 92 if(errcode == WSAEWOULDBLOCK) //表示沒有客戶端發起鏈接,繼續循環 93 { 94 Sleep(100); 95 continue; 96 } 97 else 98 { 99 printf("accept failed!"); 100 101 closesocket(sServer); //鏈接失敗,關閉服務器套接字並釋放套接字庫 102 WSACleanup(); // 103 return -1; 104 } 105 } 106 107 break; // 108 } 109 110 //接收數據 111 while(true) 112 { 113 retVal=recv(sClient,buf,strlen(buf),0); 114 if(retVal == SOCKET_ERROR) 115 { 116 errcode=WSAGetLastError(); //這個變量errcode沒有重複定義嗎? 117 if(errcode == WSAEWOULDBLOCK) // 118 { 119 Sleep(100); 120 continue; 121 } 122 else 123 { 124 if(errcode==WSAETIMEDOUT || errcode==WSAENETDOWN) 125 { 126 closesocket(sClient); 127 closesocket(sServer); 128 WSACleanup(); 129 return -1; 130 } 131 } 132 } 133 134 if(buf == "quit") //若是接收數據爲"quit",則發送回顯"quit" 135 { 136 retVal=send(sClient,buf,strlen(buf),0); 137 break; 138 } 139 else 140 { 141 //發送數據 142 while(true) 143 { 144 retVal=send(sClient,buf,strlen(buf),0); //a.回顯接收數據;b.第四個參數:0? 145 if(retVal == SOCKET_ERROR) //錯誤處理 146 { 147 errcode=WSAGetLastError(); 148 if(errcode == WSAEWOULDBLOCK) // 149 { 150 Sleep(100); 151 continue; 152 } 153 else 154 { 155 closesocket(sClient); 156 closesocket(sServer); 157 WSACleanup(); 158 return -1; 159 160 } 161 } 162 163 break; //若是發送數據成功,則退出循環 164 } 165 166 } 167 } 168 169 }
1 //Client.cpp 2 #include <stdio.h> 3 #include <WinSock2.h> //winsock.h 4 #pragma comment(lib,"ws2_32.lib"); //wsock32.lib 5 6 #include <iostream> 7 using namespace std; 8 9 #include <string.h> //strcpy函數 10 11 #define MAXSIZE 100 // 12 13 int main() 14 { 15 // 16 int retVal; 17 18 char buf[MAXSIZE]; 19 20 //初始化套接字庫 21 WORD wVersionRequest; 22 WSADATA wsadata; 23 24 wVersionRequest=MAKEWORD(2,2); 25 26 retVal=WSAStartup(wVersionRequest,&wsadata); 27 if(retVal == SOCKET_ERROR) 28 { 29 printf("WSAStartup failed!"); 30 31 return -1; 32 } 33 34 //建立套接字 35 SOCKET sClient; 36 sClient=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); 37 if(sClient == INVALID_SOCKET) 38 { 39 printf("socket failed!"); 40 41 WSACleanup(); 42 return -1; //每次檢測到失敗後,即須要返回 43 } 44 45 //設置爲非阻塞模式 46 int imode=1; 47 retVal=ioctlsocket(sClient,FIONBIO,(u_long *)&imode); 48 if(retVal == SOCKET_ERROR) 49 { 50 printf("ioctlsocket failed!"); 51 52 closesocket(sClient); 53 WSACleanup(); 54 return -1; 55 } 56 57 58 //發起鏈接 59 sockaddr_in addrServ; 60 addrServ.sin_family=AF_INET; //表示使用的是,TCP/IP地址家族 61 addrServ.sin_port =htons(5000); //爲何要使用htons宏? 62 addrServ.sin_addr.S_un.S_addr=inet_addr("192.168.0.102"); 63 64 int len=sizeof(sockaddr_in); //sizeof只是一個運算符,不是函數 65 66 while(true) 67 { 68 retVal=connect(sClient,(sockaddr *)&addrServ,len); //鏈接到某一個具體的服務器 69 if(retVal == INVALID_SOCKET) 70 { 71 int errcode=WSAGetLastError(); 72 if(errcode==WSAEWOULDBLOCK || errcode==WSAEINVAL) //表示服務器端未準備好,繼續循環 73 { 74 Sleep(100); 75 continue; 76 } 77 else 78 { 79 if(errcode == WSAEISCONN) //鏈接成功,則退出 80 { 81 break; 82 } 83 else //不然鏈接失敗,關閉客戶端套接字並釋放套接字庫 84 { 85 printf("connect failed!"); 86 87 closesocket(sClient); 88 WSACleanup(); // 89 return -1; 90 } 91 } 92 } 93 94 } 95 96 //發送數據 97 while(true) 98 { 99 // 100 //scanf(buf); 101 //cin>>buf; 102 103 strcpy(buf,"Hello TCP!"); 104 105 retVal=send(sClient,buf,strlen(buf),0); //a.回顯接收數據;b.第四個參數:0? 106 if(retVal == SOCKET_ERROR) //錯誤處理 107 { 108 int errcode=WSAGetLastError(); 109 if(errcode == WSAEWOULDBLOCK) // 110 { 111 Sleep(100); 112 continue; 113 } 114 else 115 { 116 printf("send failed!"); 117 118 closesocket(sClient); 119 //closesocket(sServer); 120 WSACleanup(); 121 return -1; 122 123 } 124 } 125 126 break; //若是發送數據成功,則退出循環 127 } 128 129 //接收數據 130 while(true) 131 { 132 retVal=recv(sClient,buf,strlen(buf),0); 133 if(retVal == SOCKET_ERROR) 134 { 135 int errcode=WSAGetLastError(); //這個變量errcode沒有重複定義嗎? 136 if(errcode == WSAEWOULDBLOCK) // 137 { 138 Sleep(100); 139 continue; 140 } 141 else 142 { 143 if(errcode==WSAETIMEDOUT || errcode==WSAENETDOWN) 144 { 145 printf("recv failed!"); 146 147 closesocket(sClient); 148 //closesocket(sServer); 149 WSACleanup(); 150 return -1; 151 } 152 } 153 } 154 155 break; 156 } 157 }
1.ios
#include <winsock2.h> //winsock.h (2種套接字版本)
#pragma comment(lib,"ws2_32.lib") //wsock32.lib服務器
2.socket
retVal=ioctlsocket(sServer,FIONBIO,(u_long *)&imode); //第3個參數一般設爲1(同時第2個參數設爲FIONBIO),表示非阻塞模式函數
3.ui
a. //綁定套接字並將其設置爲監聽狀態
SOCKADDR_IN addrServ;
addrServ.sin_family=AF_INET;
addrServ.sin_port =htons(5000);
addrServ.sin_addr.S_un.S_addr=inet_addr("192.168.0.102");spa
retVal=bind(sServer,(SOCKADDR *)&addrServ,sizeof(addrServ)); //綁定套接字到某一個具體的服務器調試
這一段代碼代表,bind函數須要定義一個addrServ,而且要爲每一個字段賦值。code
b. retVal=listen(sServer,1); //第二個參數,表示最大鏈接數目blog
4.ci
//接受鏈接
sockaddr_in addrClient; //定義一個臨時地址,用於接受鏈接(注意:某個客戶端由Client.cpp肯定)
int len=sizeof(sockaddr_in);
SOCKET sClient;
int errcode;
while(true)
{
sClient=accept(sServer,(sockaddr *)&addrClient,&len);
if(sClient == INVALID_SOCKET)
{
errcode=WSAGetLastError();
if(errcode == WSAEWOULDBLOCK) //表示沒有客戶端發起鏈接,繼續循環
{
……
5.
retVal=recv(sClient,buf,strlen(buf),0);//第4個參數,表示影響該函數的行爲(一般設爲0)
retVal=send(sClient,buf,strlen(buf),0); //a.回顯接收數據;b.第四個參數:0?
------------------------------------------------------------------------------------------------
1.
addrServ.sin_port =htons(5000); //爲何要使用htons宏?前者的字段類型和宏的返回值類型一致
addrServ.sin_addr.S_un.S_addr=inet_addr("192.168.0.102"); //同理,後者函數的返回值類型和字段類型一致
2.
//scanf(buf); //問題①:爲什麼這兩個發送字符串我發送不了?
//cin>>buf;
strcpy(buf,"Hello TCP!"); //發送固定字符串
3.
問題②:下次繼續作實驗,bind failed的緣由,並且是Client.cpp端出現的 真奇怪?(本身有調試,結果發現port字段和本身設置的不一致,不知爲什麼)
http://qxzbgzh.blog.51cto.com/blog/2821013/875991