天天看點

WINDOWS SOCKET 重疊I/O 事件對象

學習重疊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");

  }

 }  

}

繼續閱讀