1. 程式人生 > >WSAsocket客戶端請求伺服器示例

WSAsocket客戶端請求伺服器示例

DWORD WSARequestServerVerifyCode(const std::string server_ip, int server_port, const std::string& request_verify_code_xml_)
{
	if (request_verify_code_xml_.length() <= 0) 
		return -1;

	USES_CONVERSION;
	unsigned short port = server_port;//8866
	int socket_type = SOCK_STREAM;
	sockaddr_in	server;
	SOCKET sockConn;

	char recvBuffer[128] = {0};
	WSABUF wsabuf;
	wsabuf.buf=recvBuffer;
	wsabuf.len=sizeof(recvBuffer);
	DWORD NoBR;
	DWORD flags=0;

	int nErr = -1;
	//wsaevetn
	WSAEVENT hWsaEvent = WSACreateEvent();
	if (WSA_INVALID_EVENT == hWsaEvent)
	{
		nErr = WSAGetLastError();
		return nErr;
	}

	HANDLE hEvents[1];
	hEvents[0] = hWsaEvent;
	WSAOVERLAPPED wsaOverlap;
	ZeroMemory(&wsaOverlap, sizeof(wsaOverlap));
	wsaOverlap.hEvent = hWsaEvent;
	//start up socket
	server.sin_addr.s_addr = inet_addr(server_ip.c_str());   
	server.sin_family = AF_INET;
	server.sin_port = htons(port);//
	//startup wsasocket
	sockConn = WSASocket(AF_INET, socket_type,0, NULL, 0, WSA_FLAG_OVERLAPPED );
	if (INVALID_SOCKET == sockConn)
	{
		nErr = WSAGetLastError();
		WSACloseEvent(hWsaEvent);
		return nErr;
	}

	//connect
	if (connect(sockConn,(SOCKADDR*)&server,sizeof(server)) == SOCKET_ERROR)
	{
		nErr = WSAGetLastError();
		closesocket(sockConn);
		WSACloseEvent(hWsaEvent);
		return nErr;
	}

	//head
	ProtoHead ProtoHead;
	memcpy(ProtoHead.szID, "PROTOHEAD", 9);
	ProtoHead.dwOption = 0;

	ProtoHead.dwLen = (DWORD) request_verify_code_xml_.size(); //  request_verify_code_xml_
	int nTotalLen = (int) (sizeof(ProtoHead) + request_verify_code_xml_.size() );
	char *pSendBuf = (char*)malloc(nTotalLen);
	int nLeftLen = nTotalLen;
	int nSentLen = 0;
	memcpy(pSendBuf, &ProtoHead, sizeof(ProtoHead));
	memcpy(pSendBuf + sizeof(ProtoHead), request_verify_code_xml_.c_str(), request_verify_code_xml_.size());
	char *ptr = pSendBuf;
	while(nLeftLen > 0)
	{
		nSentLen = send(sockConn, ptr, nLeftLen, 0);
		if (SOCKET_ERROR == nSentLen)
		{
			nErr = WSAGetLastError();
			closesocket(sockConn);
			WSACloseEvent(hWsaEvent);
			free(pSendBuf);
			return nErr;
		}
		nLeftLen = nTotalLen - nSentLen;
		ptr+=nSentLen;
	}
	free(pSendBuf);
	//recv
	int nRecvLen = WSARecv(sockConn, &wsabuf, 1,&NoBR ,&flags, &wsaOverlap,NULL);
	if (SOCKET_ERROR == nRecvLen)
	{
		nErr = WSAGetLastError();
		if (WSA_IO_PENDING != nErr)//other wrong reseaons
		{
			closesocket(sockConn);
			WSACloseEvent(hWsaEvent);
			return nErr;
		}
	}
	//WaitForMultipleObjects
	DWORD dwRet = WaitForMultipleObjects(1,hEvents, FALSE, 15*1000 );
	if (WSA_WAIT_FAILED == dwRet || WSA_WAIT_TIMEOUT == dwRet)
	{
		closesocket(sockConn);
		WSACloseEvent(hWsaEvent);
		return nErr;
	}
	else if (WAIT_OBJECT_0 + 1 == dwRet)
	{
		//exit event;
		closesocket(sockConn);
		WSACloseEvent(hWsaEvent);
	}

	//handle
	DWORD dwTransferedLen = 0;
	if (WSAGetOverlappedResult(sockConn, &wsaOverlap, &dwTransferedLen, FALSE, &flags) == FALSE)
	{
		nErr = WSAGetLastError();
		closesocket(sockConn);
		WSACloseEvent(hWsaEvent);
		return nErr;
	}

	closesocket(sockConn);
	WSACloseEvent(hWsaEvent);
	if (dwTransferedLen == 0) //peer closed
	{
		nErr = WSAGetLastError();
		return nErr;
	}

	if (_strnicmp(recvBuffer,"PROTOHEAD",strlen("PROTOHEAD"))==0)
	{
		ProtoHead *pProtoHead = (ProtoHead*)recvBuffer;
		const char *pXml = recvBuffer + sizeof(ProtoHead);
		std::string strXml(pXml, pProtoHead->dwLen);
		TiXmlDocument doc;
		doc.Parse(strXml.c_str(), 0 , TIXML_ENCODING_LEGACY);
		TiXmlElement *root = doc.RootElement();
		int nResultCode = -1;
		root->Attribute("result", &nResultCode);
		if ( 1 != nResultCode)
		{
			return nResultCode;
		}
	}
	return -1;
}