服务器:
#define WIN32_LEAN_AND_MEAN
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <WinSock2.h>
#include <Windows.h>
#include <iostream>
#include <stdio.h>
#include <vector>
#include <tchar.h>
#pragma comment(lib,"ws2_32.lib")
using namespace std;
vector<SOCKET> clients;
int sock_factory(SOCKET _clientSock)
{
char _recvBuf[128] = {}; //缓冲区
//5 接收客户端数据
int nLen = recv(_clientSock, _recvBuf, 128, 0);
if (nLen <= 0)
{
//客户端退出
printf("客户端退出");
return -1;
}
printf("recv[%d]: %s\n", _clientSock, _recvBuf);
//6 处理请求
if (0 == strcmp(_recvBuf, "getName"))
{
char msgBuf[] = "WYP";
send(_clientSock, msgBuf, strlen(msgBuf) + 1, 0);
}
else if (0 == strcmp(_recvBuf, "getAge"))
{
char msgBuf[] = "18";
send(_clientSock, msgBuf, strlen(msgBuf) + 1, 0);
}
else
{
char msgBuf[] = "send success\n";
send(_clientSock, msgBuf, strlen(msgBuf) + 1, 0);
}
return 0;
}
int main()
{
//启动windows socket 2.x环境
WORD ver = MAKEWORD(2,2);
WSADATA dat;
WSAStartup(ver, &dat);
//用Socket API建立建议TCP服务器
//1 建立 socket
SOCKET _sock = socket(AF_INET, SOCK_STREAM , IPPROTO_TCP);
if (INVALID_SOCKET == _sock)
{
printf("socket初始化失败...\n");
return -1;
}
//2 bind a port
sockaddr_in _sin = {};
_sin.sin_family = AF_INET;
_sin.sin_port = htons(8888);//host to net unsigned short
_sin.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
if (SOCKET_ERROR == bind(_sock, (sockaddr*)&_sin, sizeof(_sin)))
{
printf("绑定失败...\n");
}
else
{
printf("绑定成功.\n");
}
//3 listen port
if(SOCKET_ERROR == listen(_sock, 5))//5:五个连接
{
printf("监听失败...\n");
}
else
{
printf("监听成功.\n");
}
while (true)
{
fd_set fdRead;
fd_set fdWrite;
fd_set fdExp;
FD_ZERO(&fdRead);
FD_ZERO(&fdWrite);
FD_ZERO(&fdExp);
FD_SET(_sock, &fdRead);
FD_SET(_sock, &fdWrite);
FD_SET(_sock, &fdExp);
for (int n = (int)clients.size() - 1; n >= 0; n--)
{
FD_SET(clients[n], &fdRead);
}
//select(int nfds); nfds是指fd_set集合中所有描述符(socket)的范围,而不是数量。
//即所有文件描述符最大值 + 1 , 在Windows中这个参数可以写0
timeval over_time = { 1,0 };
int ret = select(_sock, &fdRead, &fdWrite, &fdExp, &over_time);
if (ret < 0)
{
printf("select任务结束");
break;
}
if (FD_ISSET(_sock, &fdRead))//sock 是否在集合中
{
FD_CLR(_sock, &fdRead);
//4 accept 等待客户端连接
sockaddr_in clientAddr = {};
int nAddrLen = sizeof(sockaddr_in);
SOCKET _clientSock = INVALID_SOCKET;
_clientSock = accept(_sock, (sockaddr*)&clientAddr, &nAddrLen);
if (INVALID_SOCKET == _clientSock)
{
printf("错误,接受的客户端无效...\n");
}
printf("new client:%s : %d\n", inet_ntoa(clientAddr.sin_addr), clientAddr.sin_port);
clients.push_back(_clientSock);
}
for (int n = 0;n < fdRead.fd_count; n++)
{
if (-1 == sock_factory(fdRead.fd_array[n]))
{
auto iter = find(clients.begin(), clients.end(), fdRead.fd_array[n]);
if (iter != clients.end())
{
clients.erase(iter);
}
}
}
//printf("空闲\n");
}
for (size_t n = clients.size() - 1; n >= 0; n--)
{
closesocket(clients[n]);
}
//6 close socket
WSACleanup();
printf("退出");
getchar();
return 0;
}