OpenClonk
TstC4NetIO.cpp
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 2005-2006, Peter Wortmann
5  * Copyright (c) 2005, Günther Brammer
6  * Copyright (c) 2009-2016, The OpenClonk Team and contributors
7  *
8  * Distributed under the terms of the ISC license; see accompanying file
9  * "COPYING" for details.
10  *
11  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
12  * See accompanying file "TRADEMARK" for details.
13  *
14  * To redistribute this file separately, substitute the full license texts
15  * for the above references.
16  */
17 
18 #include "C4Include.h"
19 #include "network/C4NetIO.h"
20 #include "lib/C4Random.h"
21 
22 #ifdef _WIN32
24 #include <mmsystem.h>
25 #else
26 #include <arpa/inet.h>
27 #endif
28 
29 using namespace std;
30 
31 bool fHost;
32 int iCnt = 0, iSize = 0;
33 char DummyData[1024 * 1024];
34 
35 #define ASYNC_CONNECT
36 
37 // TCP otherwise
38 #define USE_UDP
39 
40 class MyCBClass : public C4NetIOMan
41 {
42  unsigned int tTime, iPcks;
43 public:
44  virtual bool OnConn(const C4NetIO::addr_t &addr, const C4NetIO::addr_t &addr2, C4NetIO *pNetIO)
45  {
46  cout << "got connection from " << inet_ntoa(addr.sin_addr) << endl;
47  tTime = C4TimeMilliseconds::Now();
48  iPcks = 0;
49 
50 #ifdef ASYNC_CONNECT
51  if (!fHost)
52  {
53  DummyData[0] = 0;
54  if (!pNetIO->Send(C4NetIOPacket(DummyData, iSize, true, addr)))
55  cout << " Fehler: " << (pNetIO->GetError() ? pNetIO->GetError() : "bla") << endl;
56  }
57 #endif
58  return true;
59  }
60  virtual void OnPacket(const class C4NetIOPacket &rPacket, C4NetIO *pNetIO)
61  {
63  if (tNow > tTime + 1000)
64  {
65  cout << iPcks << " packets in " << tNow - tTime << " ms (" << iPcks * 1000 / (tNow - tTime) << " per second, " << (iPcks ? (tNow - tTime) * 1000 / iPcks : -1u) << "us per packet)" << endl;
66  tTime = C4TimeMilliseconds::Now();
67  iPcks = 0;
68  }
69  if (!rPacket.getStatus())
70  {
71  // dummys
72  DummyData[0] = 1;
73  C4NetIOPacket Dummy(DummyData, iSize, true, rPacket.getAddr());
74  for (int i = 0; i < iCnt; i++)
75  {
76  if (!pNetIO->Send(Dummy))
77  cout << " Fehler: " << (pNetIO->GetError() ? pNetIO->GetError() : "bla") << endl;
78  }
79  // pong
80  pNetIO->Send(rPacket);
81  iPcks++;
82  }
83  // cout << "got " << rPacket.GetSize() << " bytes of data (" << int(*rPacket.GetData()) << ")" << endl;
84  }
85  virtual void OnDisconn(const C4NetIO::addr_t &addr, C4NetIO *pNetIO, const char *szReason)
86  {
87  cout << "client from " << inet_ntoa(addr.sin_addr) << " disconnected (" << szReason << ")" << endl;
88  }
89  virtual void OnError(const char *strError, C4NetIO *pNetIO)
90  {
91  cout << "network error: " << strError << endl;
92  };
93 };
94 
95 int main(int argc, char * argv[])
96 {
97 
98  int i;
99  for (i = 0; i < sizeof(DummyData); i++)
100  DummyData[i] = 'A' + i % 100;
101 
102  FixedRandom(time(nullptr));
103 
104 #ifdef USE_UDP
105  C4NetIOUDP NetIO;
106 #else
107  C4NetIOTCP NetIO;
108 #endif
109 
110  C4NetIO *pNetIO = &NetIO;
111  MyCBClass CBClass;
112  CBClass.AddIO(pNetIO);
113 
114 #ifdef HAVE_WINSOCK
115  WSADATA wsaData;
116 
117  WSAStartup(0x0202, &wsaData);
118 #endif
119 
120  C4NetIO::addr_t addr;
121  // Default
122  addr.sin_addr.s_addr = inet_addr("127.0.0.1");
123  addr.sin_port = htons(11111);
124  addr.sin_family = AF_INET;
125  short iPort = 0;
126 
127  for (i = 1; i < argc; ++i)
128  {
129  std::string arg(argv[i]);
130  int n;
131  if (arg == "--server")
132  {
133  fHost = true;
134  if (!iPort) iPort = 11111;
135  }
136  else if ((n = arg.find("--port=")) != -1)
137  {
138  std::istringstream stream(std::string(arg.begin() + n + sizeof("--port="), arg.end()));
139  stream >> iPort;
140  }
141  else if ((n = arg.find("--size=")) != -1)
142  {
143  std::istringstream stream(std::string(arg.begin() + n + sizeof("--size="), arg.end()));
144  stream >> iSize;
145  }
146  else
147  {
148  if (!ResolveAddress(argv[i], &addr, 11111)) cout << "Fehler in ResolveAddress(" << argv[i] << ")" << std::endl;
149  if (!iPort) iPort = 11112;
150  }
151  }
152  if (argc == 1)
153  {
154 #ifndef _WIN32
155  cout << "Possible usage: " << argv[0] << " [--server] [address[:port]] --port=port --size=size" << std::endl << std::endl;
156 #endif
157 
158  cout << "Server? (j/n)";
159  char cChoice;
160  do
161  cin >> cChoice;
162  while (tolower(cChoice) != 'n' && tolower(cChoice) != 'j');
163 
164  fHost = (tolower(cChoice) == 'j');
165 
166  if (cChoice == 'J' || cChoice == 'N')
167  {
168  iPort = (cChoice == 'J' ? 11111 : 11112);
169  iCnt = 0;
170  iSize = 0;
171  }
172  else
173  {
174  cout << "Port?";
175  cin >> iPort;
176 
177  cout << "Dummys?";
178  do
179  cin >> iCnt;
180  while (iCnt < 0);
181 
182  cout << "Größe?";
183  do
184  cin >> iSize;
185  while (iSize < 1 || iSize > 1024);
186  }
187  if (!fHost)
188  {
189  char szAddr[1024];
190  int iDPort;
191  if (cChoice == 'N')
192  {
193  strcpy(szAddr, "127.0.0.1");
194  iDPort = 11111;
195  }
196  else
197  {
198  cout << "Wohin (Adresse)? ";
199  cin >> szAddr;
200 
201  cout << "Wohin (Port)? ";
202  cin >> iDPort;
203  }
204  addr.sin_addr.s_addr = inet_addr(szAddr);
205  addr.sin_port = htons(iDPort);
206  addr.sin_family = AF_INET;
207  }
208  }
209  cout << "\nC4NetIO Init...";
210 
211  if (!NetIO.Init(iPort))
212  {
213  cout << " Fehler: " << NetIO.GetError() << endl;
214  return 0;
215  }
216 
217  cout << " ok" << endl;
218 
219 
220  if (fHost)
221  {
222 
223  cout << " Broadcast...";
224  C4NetIO::addr_t addr;
225  if (!NetIO.InitBroadcast(&addr))
226  {
227  cout << " Fehler: " << NetIO.GetError() << endl;
228  return 0;
229  }
230 
231  cout << " ok" << endl;
232 
233  cout << " Thread...";
234 
235  if (!CBClass.Start())
236  {
237  cout << " Fehler!" << endl;
238  return 0;
239  }
240 
241  cout << " ok" << endl;
242 
243  cout << "listening... " << endl;
244 
245  }
246  else
247  {
248  cout << " Thread...";
249 
250  if (!CBClass.Start())
251  {
252  cout << " Fehler!" << endl;
253  return 0;
254  }
255 
256  cout << " ok" << endl;
257 
258  cout << "verbinden mit " << inet_ntoa(addr.sin_addr) << ":" << ntohs(addr.sin_port) << "...\n";
259 #ifdef ASYNC_CONNECT
260  NetIO.Connect(addr);
261 #else
262  if (!fHost)
263  {
264  int iBufLen = 5000;
265  char *pBuf = new char [iBufLen];
266  for (int i = 0; i < 10; i++)
267  {
268  *pBuf = i;
269  if (!pNetIO->Send(C4NetIOPacket(pBuf, iBufLen, true, addr)))
270  cout << " Fehler: " << (pNetIO->GetError() ? pNetIO->GetError() : "bla") << endl;
271  }
272  }
273 #endif
274  }
275 
276  while (std::cin.get() == 10);
277 
278  CBClass.Stop();
279  NetIO.Close();
280 
281  return 1;
282 }
void FixedRandom(uint64_t seed)
Definition: C4Random.cpp:37
char DummyData[1024 *1024]
Definition: TstC4NetIO.cpp:33
int main(int argc, char *argv[])
Definition: TstC4NetIO.cpp:95
bool fHost
Definition: TstC4NetIO.cpp:31
int iCnt
Definition: TstC4NetIO.cpp:32
int iSize
Definition: TstC4NetIO.cpp:32
virtual const char * GetError() const
Definition: C4NetIO.h:286
virtual bool Send(const class C4NetIOPacket &rPacket)=0
void AddIO(C4NetIO *pNetIO, bool fSetCallback=true)
Definition: C4NetIO.cpp:3989
const C4NetIO::addr_t & getAddr() const
Definition: C4NetIO.h:317
uint8_t getStatus() const
Definition: C4NetIO.h:319
bool Connect(const addr_t &addr) override
Definition: C4NetIO.cpp:2717
bool InitBroadcast(addr_t *pBroadcastAddr) override
Definition: C4NetIO.cpp:2501
bool Init(uint16_t iPort=addr_t::IPPORT_NONE) override
Definition: C4NetIO.cpp:2472
bool Close() override
Definition: C4NetIO.cpp:2639
static C4TimeMilliseconds Now()
virtual void OnPacket(const class C4NetIOPacket &rPacket, C4NetIO *pNetIO)
Definition: TstC4NetIO.cpp:60
virtual bool OnConn(const C4NetIO::addr_t &addr, const C4NetIO::addr_t &addr2, C4NetIO *pNetIO)
Definition: TstC4NetIO.cpp:44
virtual void OnError(const char *strError, C4NetIO *pNetIO)
Definition: TstC4NetIO.cpp:89
virtual void OnDisconn(const C4NetIO::addr_t &addr, C4NetIO *pNetIO, const char *szReason)
Definition: TstC4NetIO.cpp:85