#include <iostream>
using namespace std;
#include "winsock2.h"
#pragma comment(lib, "ws2_32.lib")
#define BUF_SIZE 64
int main(int argc, char* argv[]) {
WSADATA wsd; //WSADATA變數
SOCKET sServer; //伺服器Socket
SOCKET sClient; //客戶端Socket
SOCKADDR_IN addrServ;; //伺服器地址
char buf[BUF_SIZE]; //接收資料緩衝區
int retVal; //返回值
int bufNum = 0;
//Select模式的相關變數
FD_SET socketSet; //伺服器Sockets集合
FD_SET readSet; //測試可讀性的Sockets集合
FD_SET writeSet; //測試可寫性的Sockets集合
bool bSent; //是否回傳訊息給Client的記號
//初始化Socket動態庫
if (WSAStartup(MAKEWORD(2,2), &wsd) != 0) {
cout << "WSAStartup failed!" << endl;
system("pause");
return 1;
}
//初始化Sockets集合
FD_ZERO(&socketSet);
//建立Socket
sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(INVALID_SOCKET == sServer) {
cout << "socket failed!" << endl;
WSACleanup();//釋放Socket資源;
system("pause");
return -1;
}
//將伺服器Socket加入伺服器Sockets集合
FD_SET(sServer, &socketSet);
//伺服器Socket地址
addrServ.sin_family = AF_INET;
addrServ.sin_port = htons(4999);
addrServ.sin_addr.s_addr = INADDR_ANY;
//綁定Socket
retVal = bind(sServer, (LPSOCKADDR)&addrServ, sizeof(SOCKADDR_IN));
if(SOCKET_ERROR == retVal) {
cout << "bind failed!" << endl;
closesocket(sServer); //關閉Socket
WSACleanup(); //釋放Socket資源;
system("pause");
return -1;
}
//開始監聽
retVal = listen(sServer, 1);
if(SOCKET_ERROR == retVal) {
cout << "listen failed!" << endl;
closesocket(sServer); //關閉Socket
WSACleanup(); //釋放Socket資源;
system("pause");
return -1;
}
cout << "Server is listening..." << endl;
//待續_Start
//伺服器只管接收客戶端的連線以及問候語,所以只要判斷可讀性便可
while (1) {
FD_ZERO(&readSet); //清空測試可讀性
FD_ZERO(&writeSet); //清空測試可寫性
bSent = false;
readSet = socketSet; //將要測試可讀性的Socket加入readSet
writeSet = socketSet; //將要測試可讀性的Socket加入writeSet
if (SOCKET_ERROR == select(0, &readSet, &writeSet, NULL, NULL)) {
cout << "select() returned with error " << WSAGetLastError() << endl;
closesocket(sServer); //關閉Socket
WSACleanup(); //釋放Socket資源;
system("pause");
return -1;
}
//接下來看看測試的結果
if (FD_ISSET(sServer, &readSet)) {//伺服器Socket還在集合中嗎?
//在,那表示有客戶端的連線進來了
cout << "Client is connecting...";
sClient = accept(sServer, NULL, NULL);
if(INVALID_SOCKET == sClient) {
cout << "accept failed!" << endl;
closesocket(sServer); //關閉Socket
WSACleanup(); //釋放Socket資源;
system("pause");
return -1;
}
cout << " connected." << endl;
//將客戶端Socket加入伺服器Sockets集合
FD_SET(sClient, &socketSet);
system("pause");
}
if (FD_ISSET(sClient, &readSet)) {//客戶端Socket還在集合中嗎?
//接收客戶端資料
ZeroMemory(buf, BUF_SIZE);
retVal = recv(sClient, buf, BUF_SIZE, 0);
if (SOCKET_ERROR == retVal) {
cout << "recv failed!" << endl;
closesocket(sServer); //關閉Socket
closesocket(sClient); //關閉Socket
WSACleanup(); //釋放Socket資源;
system("pause");
return -1;
}
if (0==retVal) break;
cout<<"MSG Received from Client: "<<buf<<endl;
bSent = true;
}
if (FD_ISSET(sClient, &writeSet) && bSent) {//客戶端Socket還在集合中嗎?
if (SOCKET_ERROR == retVal) {
cout << "recv failed!" << endl;
closesocket(sServer); //關閉Socket
closesocket(sClient); //關閉Socket
WSACleanup(); //釋放Socket資源;
system("pause");
return -1;
}
retVal = send(sClient, buf, strlen(buf), 0);
if (!strcmp(buf,"bye")) break;
}
Sleep(100); //休息一段時間以降低在While迴圈中CPU的使用率
}
//待續_End
//退出
closesocket(sServer); //關閉Socket
closesocket(sClient); //關閉Socket
WSACleanup(); //釋放Socket資源;
system("pause");
return 0;
}