非阻塞多线程控制台下实例

来源:互联网 发布:巴西葡萄牙语翻译软件 编辑:程序博客网 时间:2024/06/16 04:34

月月给小弟的代码~

Server:
#include <WinSock2.h>
#include <Windows.h>
#include <stdio.h>
#pragma comment(lib,"WS2_32.lib")

typedef struct tagTHREADPARAM
{
 SOCKET sClinet;
 sockaddr_in addrClient;
}THREADPARAM;

DWORD dThreadId[255];
HANDLE hThread[255];
int ThreadCount = 0;
DWORD WINAPI RecvProc(LPVOID lpParam);
DWORD WINAPI SendProc( LPVOID lpParam );

int main()
{
 WSADATA wsaData;
 SOCKET sServer;
 SOCKET sClinet;
 sockaddr_in addrServer;
 sockaddr_in addrClient;
 int iResult;
 THREADPARAM ClientSocket;

 //初始化
 if (WSAStartup(MAKEWORD(2,2),&wsaData) != 0)
 {
  printf("WSAStartuo failed!");
  return 1;
 }

 //连接Socket
 sServer = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
 if (sServer == INVALID_SOCKET)
 {
  printf("socket failed!");
  WSACleanup();
  return -1;
 }

 //bind绑定IP和端口
 addrServer.sin_family = AF_INET;
 addrServer.sin_port = htons(9990);
 addrServer.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
 iResult = bind(sServer,(const struct sockaddr*)&addrServer,sizeof(SOCKADDR_IN));
 if (iResult == SOCKET_ERROR)
 {
  printf("bind failed!");
  closesocket(sServer);
  WSACleanup();
  return -1;
 }

 
 //监听Socket
 iResult = listen(sServer,1);
 if (iResult == SOCKET_ERROR)
 {
  printf("listen failed!");
  closesocket(sServer);
  WSACleanup();
  return -1;
 }

 printf("Tcp Server start...\n");

 //等待接收,如果客户端不发包,则一直监听

 while(1)
 {
  int addrClientlen = sizeof(addrClient);
  sClinet = accept(sServer,(sockaddr FAR*)&addrClient,&addrClientlen);
  if (sClinet == INVALID_SOCKET)
  {
   printf("accept failed!");
   closesocket(sServer);
   WSACleanup();
   return -1;
  }
  ClientSocket.sClinet = sClinet;
  ClientSocket.addrClient = addrClient;
  hThread[ThreadCount] = CreateThread(NULL,0,RecvProc,&ClientSocket,0,&dThreadId[ThreadCount]);
  if (hThread[ThreadCount] == NULL)
  {
   printf("Create thread error!");
   return 1;
  }
 }
 printf("Please begin to chat\n");

 //结束清理
 closesocket(sServer);
 closesocket(sClinet);
 WSACleanup();
 system("Pause");
 return 0;
}

DWORD WINAPI RecvProc( LPVOID lpParam )
{
 ThreadCount++;
 if (lpParam == NULL)
 {
  ThreadCount--;
  ExitThread(dThreadId[ThreadCount]);
 }

 int iResult;
 char buff_reve[255];
 THREADPARAM * ClientSocket = (THREADPARAM*)lpParam;
 SOCKET sClient = ClientSocket->sClinet;
 sockaddr_in addrClient = ClientSocket->addrClient;

 THREADPARAM SeverSend;
 SeverSend.sClinet = sClient;
 SeverSend.addrClient = addrClient;

 hThread[ThreadCount] = CreateThread(NULL,0,SendProc,&SeverSend,0,&dThreadId[ThreadCount]);
 if (hThread[ThreadCount] == NULL)
 {
  printf("Create send thread error!");
  ExitThread(dThreadId[ThreadCount]);
 }

 //消息循环
 while(1)
 {
  ZeroMemory(buff_reve,128);
  iResult = recv(sClient,buff_reve,BUFSIZ,0);
  if (iResult == SOCKET_ERROR)
  {
   printf("recv failed!");
   closesocket(sClient);
   WSACleanup();
   ThreadCount--;
   ExitThread(dThreadId[ThreadCount]);
   return -1;
  }

   //等待quit,则结束消息接收
  if (strcmp(buff_reve,"quit") == 0 || strcmp(buff_reve,"结束") == 0)
  {
   iResult = send(sClient,"quit",strlen("quit"),0);
   ThreadCount = 0;
   break;
  }
  else
  {
   printf("Please input a string to send:\n");
  }
 }
}

DWORD WINAPI SendProc( LPVOID lpParam )
{
 ThreadCount++;
 if (lpParam == NULL)
 {
  ThreadCount--;
  ExitThread(dThreadId[ThreadCount]);
 }

 int iResult;
 char buff_send[255];
 THREADPARAM* SeverSend = (THREADPARAM*)lpParam;
 SOCKET sClient = SeverSend->sClinet;
 sockaddr_in addrClient = SeverSend->addrClient;

 while(1)
 {
  ZeroMemory(buff_send,128);
  printf("Please input a string to send:\n");
  scanf("%s",buff_send);
  iResult = send(sClient,buff_send,strlen(buff_send),0);
  if (iResult == SOCKET_ERROR)
  {
   printf("send failed!");
   closesocket(sClient);
   WSACleanup();
   ThreadCount--;
   ExitThread(dThreadId[ThreadCount]);
   return -1;
  }
 }
}

 

 

client:
#include <stdio.h>
#include <WinSock2.h>
#pragma comment(lib,"WS2_32.lib")

typedef struct tagTHREADPARAM
{
 SOCKET sClinet;
 sockaddr_in addrClient;
}THREADPARAM;

DWORD dThreadId[255];
HANDLE hThread[255];
int ThreadCount = 0;
HANDLE hEvent;
DWORD WINAPI RecvProc(LPVOID lpParam);
DWORD WINAPI SendProc( LPVOID lpParam );

int main()
{
 WSADATA wsaData;
 SOCKET sClinet;
 sockaddr_in addrClient;
 int iResult;
 char ServerIP[32];

 ZeroMemory(ServerIP,32);
 printf("Please input server's IP:");
 scanf("%s",ServerIP);

 //初始化
 if (WSAStartup(MAKEWORD(2,2),&wsaData) != 0)
 {
  printf("WSAStartuo failed!");
  return 1;
 }

 //连接Scocket
 sClinet = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
 if (sClinet == INVALID_SOCKET)
 {
  printf("socket failed!");
  WSACleanup();
  return -1;
 }

 //连接服务器
 addrClient.sin_family = AF_INET;
 addrClient.sin_port = htons(9990);
 addrClient.sin_addr.S_un.S_addr = inet_addr(ServerIP);
 int addrlen = sizeof(addrClient);
 iResult = connect(sClinet,(const sockaddr*)&addrClient,sizeof(addrClient));
 if (iResult == SOCKET_ERROR)
 {
  printf("connect failed!");
  closesocket(sClinet);
  WSACleanup();
  return -1;
 }

 hEvent = CreateEvent(NULL,FALSE,FALSE,L"ClientEvent");
 THREADPARAM ClientSocket;
 ClientSocket.sClinet = sClinet;
 ClientSocket.addrClient = addrClient;
 hThread[ThreadCount] = CreateThread(NULL,0,RecvProc,&ClientSocket,0,&dThreadId[ThreadCount]);
 if (hThread[ThreadCount] == NULL)
 {
  printf("Create thread error!");
  return 1;
 }

 printf("Please begin to chat\n");
 //消息接收

 WaitForSingleObject(hEvent,INFINITE);

 closesocket(sClinet);
 WSACleanup();
 system("Pause");
 return 0;
}

DWORD WINAPI RecvProc(LPVOID lpParam)
{
 ThreadCount++;
 if (lpParam == NULL)
 {
  ThreadCount--;
  ExitThread(dThreadId[ThreadCount]);
 }

 int iResult;
 char buff_reve[255];
 THREADPARAM* ClientSocket = (THREADPARAM*)lpParam;
 SOCKET sClient = ClientSocket->sClinet;
 sockaddr_in addrClient = ClientSocket->addrClient;

 THREADPARAM SeverSend;
 SeverSend.sClinet = sClient;
 SeverSend.addrClient = addrClient;

 hThread[ThreadCount] = CreateThread(NULL,0,SendProc,&SeverSend,0,&dThreadId[ThreadCount]);
 if (hThread[ThreadCount] == NULL)
 {
  printf("Create send thread error!");
  ExitThread(dThreadId[ThreadCount]);
 }

 //消息循环
 while(1)
 {
  ZeroMemory(buff_reve,128);
  iResult = recv(sClient,buff_reve,BUFSIZ,0);
  if (iResult == SOCKET_ERROR)
  {
   printf("recv failed!");
   closesocket(sClient);
   WSACleanup();
   ThreadCount--;
   ExitThread(dThreadId[ThreadCount]);
   return -1;
  }

  //等待quit,则结束消息接收
  if (strcmp(buff_reve,"quit") == 0 || strcmp(buff_reve,"结束") == 0)
  {
   iResult = send(sClient,"quit",strlen("quit"),0);
   ThreadCount = 0;
   break;
  }
  else
  {
   printf("Please input a string to send:\n");
  }
 }
 ThreadCount--;
 if (ThreadCount == 0)
 {
  SetEvent(hEvent);
 }
}

DWORD WINAPI SendProc( LPVOID lpParam )
{
 ThreadCount++;
 if (lpParam == NULL)
 {
  ThreadCount--;
  ExitThread(dThreadId[ThreadCount]);
 }

 int iResult;
 char buff_send[255];
 THREADPARAM* SeverSend = (THREADPARAM*)lpParam;
 SOCKET sClient = SeverSend->sClinet;
 sockaddr_in addrClient = SeverSend->addrClient;

 while(1)
 {
  ZeroMemory(buff_send,128);
  printf("Please input a string to send:\n");
  scanf("%s",buff_send);
  iResult = send(sClient,buff_send,strlen(buff_send),0);
  if (iResult == SOCKET_ERROR)
  {
   printf("send failed!");
   closesocket(sClient);
   WSACleanup();
   ThreadCount--;
   ExitThread(dThreadId[ThreadCount]);
   return -1;
  }
 }
 ThreadCount--;
 if (ThreadCount == 0)
 {
  SetEvent(hEvent);
 }
}

 

原创粉丝点击