windows C socket 线程池

DWORD WINAPI WorkItem(LPVOID lpParameter) ;
/*有加WINAPI的函数基本可以说明系统将在某个时候会自己调用着个函数
WINAPI 即 __stdcall ,他是函数调用约定的一种,函数调用约定主要约束了两件事
1.参数传递顺序,2.调用堆栈由谁(调用函数或被调用函数)清理
__stdcall表示 1.参数从右向左压入堆栈, 2.函数被调用者修改堆栈 
*/
int main()
{
//	cin>>FLAG;
	//线程池开辟
	CompleteEvent = CreateEvent(NULL, FALSE, FALSE, NULL); 
//	BeginTime = GetTickCount(); 

	//连接创建阶段
    WSADATA wsaData;
	if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) {
		printf("WSAStartup failed !\n");
	//	return -1;
	}
	//创建监听套接字
	SOCKET sockfd;
	if ( (sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) ) == INVALID_SOCKET) 
	{
		printf("socket failed !\n");
		WSACleanup();
	//	return -1;
	}

	//设置服务器地址
	struct sockaddr_in servaddr;
	memset(&servaddr, 0,sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons(9999);
	servaddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);   

	//绑定socket地址结构到监听套接字
	if (bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0) {
		printf("bind failed !\n");
		closesocket(sockfd);
		WSACleanup();
	}

	//在Server上进行监听
	if (listen(sockfd, 4) != 0) {
		printf("listen failed !\n");
		closesocket(sockfd);
		WSACleanup();
	//	return -1;
	//	break;
	}

	//接受客户端的连接请求
	printf("TCP Server Start...\n");

	HINSTANCE hInst=LoadLibrary("Kernel32.DLL"); //载入指定的动态链接库,并将它映射到当前进程使用的地址空间。
	//一旦载入,即可访问库内保存的资源,成功则返回库模块的句柄,零表示失败。会设置GetLastError
	if(hInst) 
	{ 
		typedef BOOL(WINAPI * MYFUNC)(LPTHREAD_START_ROUTINE, PVOID,ULONG); 
		//声明MYFUNC函数类型
		MYFUNC MyQueueUserWorkItem=NULL; 	
		//取得QueueUserWorkItem函数指针 
		MyQueueUserWorkItem=(MYFUNC)GetProcAddress(hInst,"QueueUserWorkItem"); 
		//(DLL句柄,函数名)检索指定的动态链接库(DLL)中的输出库函数地址
		//queueuserworkitem,将方法排入队列以便执行,并指定包含该方法所用数据的对象。此方法在有线程池线程变得可用时执行。
		//加载DLL,将MYFUNC指向DLL中的QueueUserWorkItem函数
		if(!MyQueueUserWorkItem) 
		{ 
			MessageBox(NULL,"获取函数地址失败","你好!",MB_OK); 
			return 0; 
		} 

		struct sockaddr_in cliaddr1;
    	int cliaddrlen = sizeof(cliaddr1);  //cliaddrlen需要有初值,作为一个值-结果参数参与函数
	    memset(&cliaddr1,0, sizeof(cliaddr1));  //memset(&cliaddr, 0, sizeof(cliaddr));
    	SOCKET connfd;
		int flag_thread = 0;
//		lp_perhandle perhandledata;
		LP_PERHANDLE prehandledata;

    //循环等待
	   while (1)
	   {
		   connfd = accept(sockfd, (struct sockaddr *)&cliaddr1, &cliaddrlen);
	

				perhandledata = new PERHANDLE();
				ZeroMemory(perhandledata, sizeof(PERHANDLE));
				
				perhandledata->connected=connfd;
				perhandledata->cliaddr=cliaddr;
		//		connected=connfd;
				perhandledata->flag=++flag_thread;
				MyQueueUserWorkItem(WorkItem, (LPVOID)&perhandledata, 0x00000010);
				int a = flag_thread;
				//WT_EXECUTELONGFUNCTION,如果线程池中线程都处于忙状态,WINDOWS将自动创建新的线程
			
	   }	
	} 
//	SetEvent(CompleteEvent); 
	FreeLibrary(hInst); 

	WaitForSingleObject(CompleteEvent, INFINITE); 
	CloseHandle(CompleteEvent); 
	return 0;
}
DWORD WINAPI WorkItem(LPVOID lpParameter) 
{
	lp_perhandle perhandle_thread=(lp_perhandle)&lpParameter;

	SOCKET connfd=perhandle_thread->connected;
	sockaddr_in client_thread=perhandle_thread->cliaddr1;
	int flag=perhandle_thread->flag;
	
//	int flag = (int)lpParameter; 

//	SOCKET connfd=connected;
	char buff[100];
	extern sockaddr_in cliaddr;
//	flag_thread++;
	extern int FLAG;
	int ret;
//	cout<<flag<<endl;
//	flag1=flag_thread;
//	cout<<flag1;
//	cout<<FLAG;
		while (true) 
		{		
//				send(connfd, "stop", sizeof(buff), 0);
				ret = recv(connfd, buff, sizeof(buff), 0);			
				if (ret == SOCKET_ERROR) 
				{
					/*
					printf("recv failed !\n");
					closesocket(connfd);
					WSACleanup();
					return -1;
					*/
					break;
				}
				//为了避免打印错误,将字符串buff结尾设成0x00
				buff[ret] = 0x00;
				//获取当前系统时间
				SYSTEMTIME st;
				GetLocalTime(&st);
				char SysDate[30];

				sprintf(SysDate, "%4d-%2d-%2d %2d:%2d:%2d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);			
				printf("%s Recv from Client [%s:%d] : %s\n", SysDate, inet_ntoa(client_thread.sin_addr), ntohs(client_thread.sin_port), buff);						
		}
	//释放资源
	closesocket(connfd);
	
	return 0; 
} 

大体是这样,最近在修改参数传输的问题,计划将套接字,地址,线程ID设计为一个数据结构,传入工作线程中
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值