Ejemplo n.º 1
0
/*接收一行数据(以"\n"结尾)
  入参:pBuf - 接收缓存
    nMaxCount - 一行的最大长度(包括"\n")
    nMicsec - socket超时值,单位:微妙,缺省:500000微妙
  出参:实际接收字节数 ,如果接收失败,返回负数,如果对方关闭,返回0
*/
int CTcp::RecvLine_n (void *pBuf, int nMaxCount, int nMicsec) const
{
    assert ((m_nSock != -1) && pBuf && (nMaxCount > 0));
    char *ptr = (char *)pBuf;
    int rn = 0, ret = 0;

    while (rn < nMaxCount)
    {
        if ((ret = Recvn (ptr + rn, 1, nMicsec)) <= 0)
            return ret;

        rn++;
        if ((rn >= 1) && (ptr[rn - 1] == '\n'))
            break;
    }

    return rn;
}
Ejemplo n.º 2
0
DWORD WINAPI Server()
{
	SOCKET sock;
	DWORD ThreadID;

	SYSTEM_INFO system_info;

	struct sockaddr_in addr;
	int iSize = sizeof(sockaddr_in);

	server_sock = CreateSocket(LampServerPort, LampServerIpAddress);
	if (server_sock == INVALID_SOCKET || server_sock == SOCKET_ERROR)
	{
		MessageBox(NULL, L"端口被占用", L"Error", MB_OK);
		beRunning = FALSE;
		UpdateServerStatus();
		return false;
	}
	beRunning = true;
	UpdateServerStatus();
	
	//创建完成端口句柄
	completionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, null, 0, 0);

	//创建工作者线程
	GetSystemInfo(&system_info);
	for (UINT i = 0; i < system_info.dwNumberOfProcessors; ++i)
	{
		HANDLE ThreadHandle;
		ThreadHandle = CreateThread(null, 0, LampWorkerThread, completionPort, 0, &ThreadID);
		CloseHandle(ThreadHandle);
	}

	HANDLE hSendLampDataToPCThread = ::CreateThread(0, 0, (LPTHREAD_START_ROUTINE)LampThread, NULL, 0, &ThreadID);
	if (hSendLampDataToPCThread != 0)
	{
		CloseHandle(hSendLampDataToPCThread);
		//MessageBox(NULL, L"SendLampDataToPCThread启动成功", L"Error", MB_OK);
	}
	char buf[40] = {0x00};

	while(server_sock != INVALID_SOCKET && beRunning)
	{
		sock = ::accept(server_sock, (sockaddr *)&addr, &iSize);
		if (sock == INVALID_SOCKET)
		{
			continue;
		}

		//设置socket为非阻塞模式
		//int iMode = 1;
		//ioctlsocket(sock, FIONBIO, (u_long FAR*) &iMode);

		fd_set fd;
		struct timeval time_out;
		FD_ZERO(&fd);
		FD_SET(sock, &fd);
		time_out.tv_sec = 20;	//设置超时时间为20s
		time_out.tv_usec = 0;

		//对于每个新的lamp连接,等待20s接受其发送的消息,若没有收到则关闭连接
		int err = select(0, &fd, NULL, NULL, &time_out);
		if ((err == SOCKET_ERROR) || (err == 0))
		{
			closemysocket(sock);
			continue;
		}

		if (FD_ISSET(sock, &fd))
		{
			//接收标记,区分连接是客户端还是节点
			char label[1] = {0x00};
			if (Recvn(sock, label, sizeof(label)) < sizeof(label))
			{
				closemysocket(sock);
				continue;
			}

			if ((u_char)label[0] == 0xAA)	//客户端连接
			{
				GUID guid;
				if (S_OK != ::CoCreateGuid(&guid))	//为每个pc端生成唯一id
				{
					closemysocket(sock);
					continue;
				}

				PCClient *pc = new PCClient(sock, guid, addr);
				{
					MutexGuard guard(PCClientListMutex);
					PCClientList.push_back(pc);
				}
				UpdatePCListView();

				HANDLE hThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)PCClientThread, (void *)pc, 0, &ThreadID);
				if (hThread != 0)
				{
					CloseHandle(hThread);//MessageBox(NULL, L"PC连接成功", L"Error", MB_OK);
				}
			}
			else if (label[0] == 0x5A)	//节点连接
			{
				//接收数据长度和节点ID
				char len_lampid[3] = {0x00};
				if (Recvn(sock, len_lampid, sizeof(len_lampid)) < sizeof(len_lampid))
				{
					closemysocket(sock);
					continue;
				}

				int len = len_lampid[0];
				char* data = new char[len + 1];
				data[0] = 0x5A;
				memcpy(data + 1, len_lampid, sizeof(len_lampid));

				if (Recvn(sock, data + 4, len - sizeof(len_lampid)) < (int)(len - sizeof(len_lampid)))
				{
					closemysocket(sock);
					continue;
				}

				SendDataToPCClient(data, len + 1);
				delete[] data;
				u_short lampid = *(u_short*)(len_lampid + 1);	//len_lampid[1]和len_lampid[2]表示id的低字节和高字节部分
				//检查此lampid是否已经存在列表中
				if (citylamp.QueryLampID(lampid))
				{
					closemysocket(sock);
					continue;
				}

				LPLampMutexSockStruct lpLMSS = new LampMutexSockStruct(sock, &addr, lampid, RECV_POSTED);
				citylamp.SetLampID2LampMutexSockMap(lampid, lpLMSS);
				UpdateLampListView(true, lampid);

				//将lampsock绑定到完成端口
				/*
				LPPER_HANDLE_DATA lpPerHandleData = (LPPER_HANDLE_DATA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PER_HANDLE_DATA));
				lpPerHandleData->Socket = sock;
				memcpy(&lpPerHandleData->ClientAddr, &addr, sizeof(sockaddr_in));
				lpPerHandleData->LampID = lampid;
				CreateIoCompletionPort((HANDLE)sock, completionPort, (DWORD)lpPerHandleData, 0);
				*/
				CreateIoCompletionPort((HANDLE)sock, completionPort, (DWORD)lpLMSS->lpPerHandleData, 0);

				/*
				LPPER_IO_DATA lpPerIOData = (LPPER_IO_DATA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PER_IO_DATA));
				lpPerIOData->Buffer.len = MAXBUFSIZE;
				lpPerIOData->Buffer.buf = lpPerIOData->szMessage;
				lpPerIOData->OperationType = RECV_POSTED;
				WSARecv(lpPerHandleData->Socket, &lpPerIOData->Buffer, 1, &lpPerIOData->NumberOfBytesTransferred, &lpPerIOData->Flags, &lpPerIOData->Overlapped, null);
				*/
				WSARecv(lpLMSS->lpPerHandleData->Socket, &lpLMSS->lpPerIOData->Buffer, 1, &lpLMSS->lpPerIOData->NumberOfBytesTransferred, &lpLMSS->lpPerIOData->Flags, &lpLMSS->lpPerIOData->Overlapped, null);
				//MessageBox(NULL, L"Lamp连接成功", L"Error", MB_OK);
			}
			else
			{
				closemysocket(sock);
				continue;
			}
		}
	}

	closemysocket(server_sock);
	WSACleanup();
	UpdateServerStatus();
	beRunning = FALSE;
	return 1;
}