第一步 初始化套接字,具体就不写了 ,重复的代码
std::cout << "this is server" << std::endl;
...
第二步 创建互斥锁
hMutex = CreateMutex(NULL, FALSE, NULL);
第三步 创建服务器套接字、绑定、监听,重复的代码
。。。
第四步 与客户端建立连接
SOCKADDR_IN addrCli;int len = sizeof(SOCKADDR_IN);while (1){SOCKET sockConn = accept(sockSrv, (SOCKADDR*)&addrCli, &len);
第四步 储存所有客户端
WaitForSingleObject(hMutex, INFINITE);clieSock[cliecount++] = sockConn;ReleaseMutex(hMutex);
先建立一个互斥锁,因为clieSock我们是设定为全局变量,不过上面代码没有写出来,只要是修改全局变量,就要设定互斥锁
第五步 既然是一对多,就要创建多线程,而且线程要同步
hthread = (HANDLE)_beginthreadex(NULL,0, &HANDLEclie, (void*)sockConn, 0, NULL);
hthread是我们提前定义的一个句柄
第六步 定义HANDLEclie函数
unsigned WINAPI HANDLEclie(void* arg)
{SOCKET hcliesock = *((SOCKET*)arg);int ilen{};char szMsg[MAX_BUFFSZIE]{};while (1){ilen = recv(hcliesock, szMsg, sizeof(szMsg), 0);if (ilen != -1){/将收到消息转发给客户端sendMsg(szMsg,ilen);}else{ break; }}
这里recv函数用来接收所有来自客户端的消息,并存储在szMsg中,然后又将SZMSG通过sendMSG函数发送出去
第七步 定义SENDMSG函数
void sendMsg(char* szMsg,int ilen)
{WaitForSingleObject(hMutex, INFINITE);for (int i=0;i< cliecount;i++){send(clieSock[i], szMsg, ilen, 0);}ReleaseMutex(hMutex);
}
这里,定义了一个互斥锁,因为我们之前定义为cliesock[]为全局变量,只是没写出来,然后发送给客户端,这里send第一个参数为目标套接字
第八步 继续完善HANDLEclie
WaitForSingleObject(hMutex, INFINITE);for (int i=0;i<cliecount;i++){if (hcliesock== clieSock[i]){while (i++ < cliecount){clieSock[i] = clieSock[i + 1];}break;}}cliecount--;
ReleaseMutex(hMutex);
如果hcliesock为-1,那么让后面的套接字顶替它,那么hcliesock什么时候为-1呢,那就是main函数中的accept函数,当它连接失败,就会把失败的套接字也写入数组clieSock中,所以只要数组中的socket为失败的socket,就删除它