代码如下:
#include <stdio.h>
#include <WinSock2.h>
#include <process.h>
#pragma comment(lib, "ws2_32.lib")
HANDLE g_hEvent = NULL;
CRITICAL_SECTION g_crs;
void myPrintf(const char* psz1, ...)
{
::EnterCriticalSection(&g_crs);
va_list arg;
va_start(arg, psz1);
vprintf(psz1, arg);
va_end(arg);
::LeaveCriticalSection(&g_crs);
}
unsigned __stdcall ClientProc(void* parm)
{
WSADATA wsData;
SOCKET skClient;
SOCKADDR_IN addrServ;
char msg[1024]={0};
fd_set rFSet;
int iRet = WSAStartup(MAKEWORD(2, 2), &wsData);
if (iRet != 0)
{
myPrintf(">>> client WSAStartup fail\n");
return 1;
}
skClient = socket(AF_INET, SOCK_STREAM, 0);
myPrintf(">>> client socket %d\n", skClient);
addrServ.sin_family = AF_INET;
addrServ.sin_port = htons(6000);
addrServ.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
WaitForSingleObject(g_hEvent, INFINITE);
iRet = connect(skClient, (sockaddr*)&addrServ, sizeof(SOCKADDR_IN));
if (iRet != 0)
{
myPrintf(">>> client connect fail\n");
goto end;
}
while (true)
{
::EnterCriticalSection(&g_crs);
printf(">>> client please input send msg: ");
scanf("%s", msg);
::LeaveCriticalSection(&g_crs);
iRet = send(skClient, msg, sizeof(msg)/sizeof(char), 0);
if (iRet == SOCKET_ERROR)
{
myPrintf(">>> client send fail\n");
break;
}
FD_ZERO(&rFSet);
FD_SET(skClient, &rFSet);
iRet = select(skClient + 1, &rFSet, NULL, NULL, NULL);
if (iRet <= 0)
{
myPrintf(">>> client select fail\n");
break;
}
memset(msg, 0, sizeof(msg)/sizeof(char));
iRet = recv(skClient, msg, sizeof(msg)/sizeof(char), 0);
if (iRet == SOCKET_ERROR)
{
myPrintf(">>> client recv fail\n");
break;
}
if (strcmp(msg, "quit") == 0)
{
myPrintf(">>> client quit\n");
break;
}
else
{
myPrintf(">>> client recv: %s\n", msg);
}
}
closesocket(skClient);
end:
myPrintf(">>> client exit\n");
WSACleanup();
return 0;
}
unsigned __stdcall ServerProc(void* param)
{
WSADATA wsData;
int iRet = WSAStartup(MAKEWORD(2, 2), &wsData);
if (iRet != 0)
{
myPrintf("server WSAStartup fail\n");
return 1;
}
char msg[1024]={0};
int len = sizeof(SOCKADDR_IN);
SOCKET skServer, skClient;
fd_set rfSet;
skServer = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
SOCKADDR_IN addrServer, addrClient;
addrServer.sin_family = AF_INET;
addrServer.sin_port = htons(6000);
addrServer.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
iRet = bind(skServer, (const sockaddr*)&addrServer, sizeof(addrServer));
if (iRet != 0)
{
myPrintf(">>> server bind fail\n");
goto end;
}
iRet = listen(skServer, 5);
if (iRet == -1)
{
myPrintf(">>> server listen fail\n");
goto end;
}
SetEvent(g_hEvent);
skClient = accept(skServer, (sockaddr*)&addrClient, &len);
if (skClient == -1)
{
myPrintf(">>> no client connect to server\n");
goto end;
}
myPrintf(">>> client %d connect to server success\n", skClient);
while (true)
{
FD_ZERO(&rfSet);
FD_SET(skClient, &rfSet);
iRet = select(skClient + 1, &rfSet, NULL, NULL, NULL);
if (iRet <= 0)
{
myPrintf(">>> server select fail\n");
break;
}
memset(msg, 0, sizeof(msg)/sizeof(char));
iRet = recv(skClient, msg, sizeof(msg)/sizeof(char), 0);
if (iRet == SOCKET_ERROR)
{
myPrintf(">>> server recv fail\n");
break;
}
else
{
myPrintf(">>> server recv: %s\n", msg);
::EnterCriticalSection(&g_crs);
myPrintf(">>> server please input command: ");
memset(msg, 0, sizeof(msg)/sizeof(char));
scanf("%s", msg);
::LeaveCriticalSection(&g_crs);
iRet = send(skClient, msg, sizeof(msg)/sizeof(char), 0);
if (iRet == SOCKET_ERROR)
{
myPrintf(">>> server send fail\n");
break;
}
}
}
end:
closesocket(skServer);
WSACleanup();
myPrintf(">>> server exit\n");
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
InitializeCriticalSection(&g_crs);
g_hEvent = CreateEventA(NULL, TRUE, FALSE, "MMClient##Event");
HANDLE hClient = (HANDLE)_beginthreadex(NULL, 0, ClientProc, NULL, 0, NULL);
HANDLE hServer = (HANDLE)_beginthreadex(NULL, 0, ServerProc, NULL, 0, NULL);
WaitForSingleObject(hClient, INFINITE);
WaitForSingleObject(hServer, INFINITE);
system("@pause");
return 0;
}