客户端:
#include <iostream>
#include <WinSock2.h>
using namespace std;
#pragma comment(lib, "ws2_32.lib")
#define SERVER_PORT 5555
#define BUFFER_SIZE 4096
#define MAX_ADDR_LEN 128
void usage();
void checkArgv(int argc, char **argv);
int nPort = SERVER_PORT;
char szBuffer[BUFFER_SIZE];
char szAddr[MAX_ADDR_LEN];
int main(int argc, char *argv[])
{
int nRet, nLen, nAddrLen, i;
SOCKET s;
SOCKADDR_IN sa;
WSAData wsaData;
WORD wVersion = MAKEWORD(2,2);
checkArgv(argc, argv);
nRet = WSAStartup(wVersion, &wsaData);
if (nRet == SOCKET_ERROR)
{
cout << "socket init error" << endl;
return 1;
}
s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s == INVALID_SOCKET)
{
cout << "socket was created failed:" << WSAGetLastError() << endl;
closesocket(s);
WSACleanup();
return 1;
}
nAddrLen = sizeof(SOCKADDR_IN);
memset(&sa, 0, nAddrLen);
sa.sin_family = AF_INET;
sa.sin_port = htons(nPort);
sa.sin_addr.s_addr = inet_addr("127.0.0.1");
nRet = connect(s, (LPSOCKADDR)&sa, nAddrLen);
if (nRet == SOCKET_ERROR)
{
cout << "socket connect() failed:" << WSAGetLastError() << endl;
closesocket(s);
WSACleanup();
return 1;
}
while (1)
{
cout << "send Message to ECHO:";
memset(szBuffer, 0, BUFFER_SIZE);
int j = 0;
while (j < sizeof(szBuffer))
{
scanf("%c", &szBuffer[j]);
if (szBuffer[j++] == '\n')
{
break;
}
}
szBuffer[j-1] = '\0';
if (strcmp(szBuffer, "quit") == 0)
{
break;
}
nRet = send(s, szBuffer, strlen(szBuffer)+1, 0);
if (nRet == SOCKET_ERROR)
{
cout << "socket send() error:" << WSAGetLastError() << endl;
break;
}
memset(szBuffer, 0, BUFFER_SIZE);
nRet = recv(s, szBuffer, BUFFER_SIZE, 0);
cout << "Server ECHO back:" << szBuffer << endl;
}
closesocket(s);
WSACleanup();
return 0;
}
void usage()
{
cout << "usage: selectMode_2.exe -i:127.0.0.1 -p:5555" << endl;
cout << "/t-i:服务器地址" << endl;
cout << "/t-p:服务器端口号,在1024到65535之间" << endl;
ExitProcess(1);
}
void checkArgv(int argc, char **argv)
{
int i;
memset(szAddr, 0, MAX_ADDR_LEN);
for (i = 1; i < argc; i ++)
{
if (argv[i][0] == '-')
{
switch(tolower(argv[i][1]))
{
case 'p':
nPort = atoi(&argv[i][3]);
cout << "端口:" << nPort << " ";
break;
case 'i':
strcpy(szAddr, &argv[i][3]);
cout << "ip:" << argv[i][3] << " ";
break;
default:
usage();
break;
}
}
}
}
服务器端:
#include <iostream>
#include <WinSock2.h>
using namespace std;
#pragma comment(lib, "ws2_32.lib")
#define DEFAULT_PORT 5555
#define BUFFER_SIZE 4096
#define DEFAULT_ADDR_LEN 128
#define MAX_CLIENT (FD_SETSIZE - 1)
int nPort = DEFAULT_PORT;
char szAddr[DEFAULT_ADDR_LEN];
char szBuffer[BUFFER_SIZE];
BOOL bInterface = FALSE;
BOOL bEchoBack = FALSE;
void usage();
void checkArgv(int argc, char **argv);
BOOL insertSocket(SOCKET *pClient, SOCKET s);
int main(int argc, char *argv[])
{
WSAData wsaData;
WORD wVersion = MAKEWORD(2,2);
SOCKET s, sClient;
SOCKADDR_IN sa, saRemote;
int nRet, nLen, i, nLeft, idx, nRecvLen;
SOCKET arrClientSocket[MAX_CLIENT];
checkArgv(argc, argv);
nRet = WSAStartup(wVersion, &wsaData);
if (nRet == SOCKET_ERROR)
{
cout << "windows socket startup error:" << WSAGetLastError() << endl;
return 1;
}
cout << "socket initalization......" << endl;
s = socket(AF_INET, SOCK_STREAM, 0);
if (INVALID_SOCKET == s)
{
cout << "socket was created error:" << WSAGetLastError() << endl;
return 1;
}
cout << "socket was created" << endl;
nLen = sizeof(SOCKADDR_IN);
memset(&sa, 0, nLen);
sa.sin_family = AF_INET;
sa.sin_port = htons(nPort);
if (bInterface) //是否使用指定的IP地址
{
sa.sin_addr.s_addr = inet_addr(szAddr);
}else{
sa.sin_addr.s_addr = htonl(INADDR_ANY);
}
nRet = bind(s, (LPSOCKADDR)&sa, nLen);
if (SOCKET_ERROR == nRet)
{
cout << "socket bind error:" << WSAGetLastError() << endl;
return 1;
}
cout << "bind was successed" << endl;
nRet = listen(s, 8);
if (nRet == SOCKET_ERROR)
{
cout << "socket listen error:" << WSAGetLastError() << endl;
return 1;
}
cout << "liten was successed" << endl;
fd_set fdRead;
for (i = 0; i < MAX_CLIENT; i ++)
{
arrClientSocket[i] = INVALID_SOCKET;
}
while(1)
{
FD_ZERO(&fdRead);
FD_SET(s, &fdRead); //置空,里边只有一个监听套接字
for (i = 0; i < MAX_CLIENT; i ++)
{
if (arrClientSocket[i] != INVALID_SOCKET)
{
FD_SET(arrClientSocket[i], &fdRead);
}
}
nRet = select(0, &fdRead, NULL, NULL, NULL);
if (SOCKET_ERROR == nRet)
{
cout << "select() error:" << WSAGetLastError() << endl;
break;
}
if (nRet > 0)
{
if (FD_ISSET(s, &fdRead))
{
sClient = accept(s, (LPSOCKADDR)&saRemote, &nLen);
insertSocket(arrClientSocket, sClient);
cout << "socket:" << sClient << "was accept" << endl;
continue;
}
for(i = 0; i < MAX_CLIENT; i ++)
{
if (FD_ISSET(arrClientSocket[i], &fdRead))
{
memset(szBuffer, 0, BUFFER_SIZE);
nRet = recv(arrClientSocket[i], szBuffer, BUFFER_SIZE, 0);
if (nRet <= 0)
{
closesocket(arrClientSocket[i]);
arrClientSocket[i] = INVALID_SOCKET;
continue;
}
nRecvLen = nRet;
cout << "socket:" << arrClientSocket[i] << " receive data(" << nRet << "):" << szBuffer << endl;
if (!bEchoBack) //将接收到的数据全部都发回到源地
{
nRet = getpeername(arrClientSocket[i], (LPSOCKADDR)&saRemote, &nLen);
if (nRet == SOCKET_ERROR)
{
cout << "getpeername() error:" << WSAGetLastError() << endl;
continue;
}
nLeft = nRecvLen;
idx = 0;
while (nLeft > 0)
{
nRet = send(arrClientSocket[i], &szBuffer[idx], nLeft, 0);
if (0 == nRet)
{
break;
}
else if (nRet == SOCKET_ERROR)
{
cout << "send() failed:" << WSAGetLastError() << endl;
break;
}
nLeft -= nRet;
idx += nRet;
}
}
}
}
}
}
closesocket(s);
WSACleanup();
return 0;
}
void usage()
{
cout << "usage: selectMode_1.exe [-p:5555] [-i:127.0.0.1] [-o]" << endl << endl;
cout << "/t-p:监听端口号:在1024到65535之间" << endl;
cout << "/t-i:监听的服务器地址" << endl;
cout << "/t-o:是否将数据发回客户端" << endl << endl;
ExitProcess(1);
}
void checkArgv(int argc, char **argv)
{
int i;
for (i = 1; i < argc; i ++)
{
if (argv[i][0] == '-')
{
switch(tolower(argv[i][1]))
{
case 'p':
nPort = atoi(&argv[i][3]);
break;
case 'i':
memset(szAddr, 0, DEFAULT_ADDR_LEN);
strcpy(szAddr, &argv[i][3]);
bInterface = TRUE;
break;
case 'o':
bEchoBack = TRUE;
break;
default:
usage();
break;
}
}
}
}
BOOL insertSocket(SOCKET *pClient, SOCKET s)
{
int i;
BOOL bResult = FALSE;
for (i = 0; i < MAX_CLIENT; i ++)
{
if (pClient[i] == INVALID_SOCKET)
{
pClient[i] = s;
bResult = TRUE;
break;
}
}
return bResult;
}