学习重叠I/O 事件对象时,在网上看了很多文章都是服务器的,而且只发送没有接收,后自己研究写了客户端,并伴有发送接收。
#include <stdio.h>
#include <WINSOCK2.H>
#pragma comment(lib, "ws2_32.lib")
#define PORT 8000
#define MSGSIZE 1024*2
#define MAX_CLIENT_NUMBER 200
SOCKET ConnectSocket;
BOOL InitSocket()
{
int nRet;
WSADATA wsaData;
SOCKADDR_IN ServerAddr;
WSAStartup(0x0202, &wsaData);
nRet = WSAStartup( 0x0202, &wsaData );
if ( nRet != 0 )
{
return false;
}
ConnectSocket = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED );
if (ConnectSocket == INVALID_SOCKET )
{
printf("WSASocket Faild Code:", WSAGetLastError());
return false;
}
ServerAddr.sin_family = AF_INET;
ServerAddr.sin_addr.S_un.S_addr = inet_addr("192.168.1.44");
ServerAddr.sin_port = htons(PORT);
if ( SOCKET_ERROR == connect(ConnectSocket, (sockaddr*)&ServerAddr, sizeof(sockaddr)))
{
printf("connect Faild Code:%d/n", WSAGetLastError());
return false;
}
return true;
}
int nRet;
char cSendBuf[1024];
char cRecvbuf[1024];
DWORD dwFlags = 0;
DWORD dwSendNumber = 0;
DWORD dwRecvNumber = 0;
DWORD dwThreadId;
DWORD dwTransferred;
WSABUF wsaBuf;
HANDLE hSendThread;
HANDLE hRecvThread;
HANDLE hMainThread;
WSAEVENT SendEvent;
WSAEVENT RecvEvent;
WSAOVERLAPPED SendOverlapped;
WSAOVERLAPPED RecvOverlapped;
DWORD WINAPI SendThread(LPVOID lpParam);
DWORD WINAPI RecvThread(LPVOID lpParam);
void Close()
{
closesocket(ConnectSocket);
WSACloseEvent(SendEvent);
if (hSendThread)
TerminateThread(hSendThread, 0);
if (hRecvThread)
TerminateThread(hRecvThread, 0);
if (hMainThread)
exit(0);
}
int main()
{
if (!InitSocket())
{
return 0;
}
hSendThread = CreateThread(NULL, 0, SendThread, NULL, 0, &dwThreadId);
hRecvThread = CreateThread(NULL, 0, RecvThread, NULL, 0, &dwThreadId);
CloseHandle(hSendThread);
CloseHandle(hRecvThread);
hMainThread = GetCurrentThread();
SuspendThread(hMainThread);
return 0;
}
DWORD WINAPI SendThread(LPVOID lpParam)
{
memset(cSendBuf, 0, 1024);
SendEvent = WSACreateEvent();
while(true)
{
ZeroMemory(cSendBuf, 1024);
ZeroMemory(&SendOverlapped, sizeof(WSAOVERLAPPED));
SendOverlapped.hEvent = SendEvent;
printf("发送的数据是:");
scanf("%s", cSendBuf);
char* p = (char*)malloc(strlen(cSendBuf) + 1);
memset(p, 0, strlen(cSendBuf));
strcpy(p, cSendBuf);
if (!strcmp(strupr(p),"EXIT"))
{
ResumeThread(hMainThread);
Close();
return 0;
}
free(p);
SendOverlapped.hEvent = SendEvent;
wsaBuf.buf = cSendBuf;
wsaBuf.len = 1024;
WSASend(ConnectSocket, &wsaBuf, 1, &dwSendNumber, dwFlags, &SendOverlapped, NULL );
if (nRet == SOCKET_ERROR)
{
if (WSAGetLastError() != WSA_IO_PENDING)
printf("Error occured at WSASend()/n");
}
nRet = WSAWaitForMultipleEvents(1, &SendEvent, FALSE, 10, FALSE);
if (nRet == WSA_WAIT_FAILED || nRet == WSA_WAIT_TIMEOUT)
{
continue;
}
WSAResetEvent(SendEvent);
WSAGetOverlappedResult(ConnectSocket,
&SendOverlapped,
&dwTransferred,
TRUE,
&dwFlags);
if (dwTransferred == 0)
{
closesocket(ConnectSocket);
WSACloseEvent(SendEvent);
return 0;
}
}
}
DWORD WINAPI RecvThread(LPVOID lpParam)
{
memset(cRecvbuf, 0, 1024);
wsaBuf.buf = cRecvbuf;
wsaBuf.len = 1024;
RecvEvent = WSACreateEvent();
ZeroMemory(cRecvbuf, 1024);
ZeroMemory(&SendOverlapped, sizeof(WSAOVERLAPPED));
RecvOverlapped.hEvent = RecvEvent;
nRet = WSARecv(ConnectSocket, &wsaBuf, 1, &dwRecvNumber, &dwFlags, &RecvOverlapped, NULL );
if (nRet == SOCKET_ERROR)
{
if (WSAGetLastError() != WSA_IO_PENDING)
printf("Error occured at WSARecv()/n");
}
while (TRUE)
{
nRet = WSAWaitForMultipleEvents(1, &RecvEvent, FALSE, 10, FALSE);
if (nRet == WSA_WAIT_FAILED || nRet == WSA_WAIT_TIMEOUT)
{
continue;
}
WSAResetEvent(RecvEvent);
WSAGetOverlappedResult(ConnectSocket,
&RecvOverlapped,
&dwTransferred,
TRUE,
&dwFlags);
if (dwTransferred == 0)
{
return 0;
}
printf("接收到数据为:%s/n", cRecvbuf);
ZeroMemory(cRecvbuf, 1024);
ZeroMemory(&RecvOverlapped, sizeof(WSAOVERLAPPED));
RecvOverlapped.hEvent = RecvEvent;
wsaBuf.buf = cRecvbuf;
wsaBuf.len = 1024;
nRet = WSARecv(ConnectSocket, &wsaBuf, 1, &dwRecvNumber, &dwFlags, &RecvOverlapped, NULL );
if (nRet == SOCKET_ERROR)
{
if (WSAGetLastError() != WSA_IO_PENDING)
printf("Error occured at WSARecv()/n");
}
}
}