📄 sample.cpp
字号:
/***********************************************************************
* Win32 / Linux Intelx86 C++ Compiler File
*--------------------------------------------------------------
* [For] { XSTUNT Sample Code: Echo Server and Client}
* [File name] { Sample.cpp }
* [Description]
* Following sample code allows 2 peers behind different NATs do direct TCP connection,
* but fail if behind the same NAT. Users should modify the code to prevent this situation.
* A client here can send message (be care of the message length) to the server and soon get
* echo message from that. The messeage "exit" will cause both exit the program.
* Build the program and run on 2 machines behind different NATs. Of course, the server
* should run before the client!
* [Notice]
* After connecting, the messeage should be sent in 60 seconds or the connection will be closed.
* [History]
* 2006.04 Kuanyu First released
***********************************************************************/
#include "ClientAPI.h"
#ifdef _WIN32
#include <conio.h>
#else
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/socket.h>
#endif
#define CONNECT_TRY_TIMES 5
#define DEF_TIMEOUT 15
#define MAX_MSG_LEN 80
//MARK the following line if you don't want to measure the connection time.
#define TEST_TIME
int main(int argc, char **argv)
{
SOCKET sServer = (SOCKET) -1;
INT32 nErr = 0, nRet = 0;
char chServerIP1[20];
char chServerIP2[20];
INT32 nTry = 0;
if ((argc != 5 && argc != 6) ||
(argc == 5 && strcmp(argv[1], "server") != 0) ||
(argc == 6 && strcmp(argv[1], "client") != 0))
{
printf("For Echo server-\n");
printf("Use: xecho server <Server ID> <STUNT Server IP1> <STUNT Server IP2>\n");
printf("Example: xecho server MyEchoServer 59.124.31.21 59.124.31.19\n");
printf("For Echo client-\n");
printf("Use: xecho client <Client ID> <Server ID> <STUNT Server IP1> <STUNT Server IP2>\n");
printf("Example: xecho client MyEchoClient MyEchoServer 59.124.31.21 59.124.31.19\n");
return -1;
}
else if (strcmp(argv[1], "server") != 0 && strcmp(argv[1], "client") != 0)
{
printf("Please check the parameter 1. It must be server or client!\n");
return -1;
}
if (strcmp(argv[1], "server") == 0)
{
strcpy(chServerIP1, argv[3]);
strcpy(chServerIP2, argv[4]);
}
else
{
strcpy(chServerIP1, argv[4]);
strcpy(chServerIP2, argv[5]);
}
///////////////////////////////////////////////////////////////////////////
//Register Sample Section//////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
if ((nRet = XInit(chServerIP1, chServerIP2, &sServer, (char*)argv[2], &nErr)) == ERR_NONE)
{
//Delay 2.5 seconds for registering!!!
#ifdef _WIN32
Sleep(2500);
#else
sleep(3);
#endif
///////////////////////////////////////////////////////////////////////////
//Listen Sample Section////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
if (strcmp(argv[1], "server") == 0)
{
printf("Strat listening...\n");
while (true)
{
char chStr[MAX_MSG_LEN];
char chChar;
int nRcv = 0;
SOCKET sListen = (SOCKET) -1;
fd_set Socks;
if (XListen(sServer, &sListen, NULL, DEF_TIMEOUT, &nErr) == ERR_NONE)
{
printf("One client successfully connected...\n");
do
{
int j = 0;
for (int i = 0; i < MAX_MSG_LEN; i++)
chStr[i] = '\0';
do
{
FD_ZERO(&Socks);
FD_SET(sListen, &Socks);
//sListen is changed to a non-blocking socket, so we need to block it.
::select(((INT32)sListen) + 1, &Socks, NULL, NULL, NULL);
nRcv = recv(sListen, &chChar, 1, 0);
chStr[j] = chChar;
j++;
}while(chChar != '\0');
if (nRcv > 0)
{
printf("Msg>> %s\n", chStr);
send(sListen, chStr, strlen(chStr), 0);
}
else
break;
}while (strcmp(chStr, "exit") != 0);
break;
}
}//end while
}//end if
///////////////////////////////////////////////////////////////////////////
//Connect Sample Section///////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
else if (strcmp(argv[1], "client") == 0)
{
//try for connection.
for (nTry = 0; nTry < CONNECT_TRY_TIMES; nTry++)
{
char chStr[MAX_MSG_LEN];
int nStart = 0, nEnd = 0;
SOCKET sConnect = (SOCKET) -1;
printf("Try direct TCP Connetion...\n");
//XConnect may fail if the listener is in the same NAT.
//In this situation, local address of the listener will be returned back through error code.
//Then try to directly connect to the address. The following sample code does not do this action.
#ifdef TEST_TIME
#ifdef _WIN32
nStart =GetTickCount();
#endif
#endif
if ((nRet = XConnect(sServer, (char*)argv[3], &sConnect, NULL, DEF_TIMEOUT, &nErr)) == ERR_NONE)
{
#ifdef TEST_TIME
#ifdef _WIN32
nEnd = GetTickCount();
printf("Successfully connected after [%d] ms.\n", nEnd - nStart);
#endif
#endif
do
{
chStr[0] = '\0';
printf("Msg>> ");
scanf("%s", chStr);
send(sConnect, chStr, strlen(chStr) + 1, 0);
chStr[0] = '\0';
if (recv(sConnect, chStr, MAX_MSG_LEN, 0) > 0)
printf("Echo>> %s\n", chStr);
}while (strcmp(chStr, "exit") != 0);
break;
}
else
{
printf("failed. ErrType(%d) ErrCode(%d)\n", nRet, nErr);
}
}//end while
if (nTry == CONNECT_TRY_TIMES)
printf("failed to connect!\n");
}//end else if
///////////////////////////////////////////////////////////////////////////
//Deregister Sample Section////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
XDeRegister(sServer, argv[2], &nErr);
printf("leave test.\n");
//end test
}
else
{
printf("Initialization failed. ErrType(%d) ErrCode(%d)\n", nRet, nErr);
}
#ifdef _WIN32
Sleep(2000);
#endif
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -