上一篇 Winsocket 一:单线程阻塞server&client程序(tcp) 在结尾处提到有一个缺点,即一次只能与一个客户端通信。本篇在服务端应用程序的主线程中不停的调用accept操作,以使服务端程序能不停地接受客户端程序发送过来的连接请求。而在接受了一个客户端的连接请求后,为每一个接受的连接请求开辟一个专门的线程来接受客户端程序发送的请求以及为具体的请求返回特定的信息。
代码如下:
#include "stdafx.h"
#include <iostream>
#include <cassert>
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib")
#define ASSERT assert
static const int c_iPort = 10001;
using std::cout;
using std::endl;
//线程参数结构体
typedef struct tagServerRecv
{
SOCKET skAccept; //已建立连接的socket
CRITICAL_SECTION *pcs;//关键段,保证每个连接的信息能每一次完整的输出到控制台
HANDLE e; //事件,保证结构体个字段改变之前将其拷贝到线程中的信号量
HANDLE t; //当前线程的内核对象
DWORD dwThreadID;//当前线程ID
}SERVER_RECV, *PSERVER_RECV;
//线程入口函数,用于server&client通信
static int ServerRecv(LPVOID LParam);
int _tmain(int argc, _TCHAR* argv[])
{
int iRet = SOCKET_ERROR;
//初始化Winsocket
WSADATA data;
ZeroMemory(&data, sizeof(WSADATA));
iRet = WSAStartup(MAKEWORD(2, 0), &data);
ASSERT(SOCKET_ERROR != iRet);
//建立服务器端程序的监听套接字
SOCKET skListen = INVALID_SOCKET;
skListen = soc