Network code

Technical discussion for those interested in Supermodel development and Model 3 reverse engineering. Prospective contributors welcome.
Forum rules
Keep it classy!

  • No ROM requests or links.
  • Do not ask to be a play tester.
  • Do not ask about release dates.
  • No drama!

Re: Network code

Postby Ian » Fri Dec 29, 2017 5:30 pm

Spindizzi clearly has a whole set of skills I don't have. Hopefully together we can make something awesome!
Ian
 
Posts: 1325
Joined: Tue Feb 23, 2016 9:23 am

Re: Network code

Postby Spindizzi » Sat Dec 30, 2017 2:16 am

I've quickly taken a look at your code, Ian. What a code !! Clearly interresting and very generic c++ coding
Something I've found strange, you have choosen to re-create socket and close them, every time we call send/recv, Is it normal ?
If I understand well, in the recv part, setting INADDR_ANY, means loopback and ip given by router (ie 192.168 ..... or other) ? In this case, no need to specify IP of the machine that launch supermodel (just port)?
Spindizzi
 
Posts: 96
Joined: Thu Nov 17, 2016 8:55 am
Location: France

Re: Network code

Postby Ian » Sat Dec 30, 2017 3:34 am

Spindizzi :)
The sockets are created / destroyed in the class constructor and destructor

Code: Select all
UDPReceive::UDPReceive()
{
   m_socket   = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);      // create the socket
   m_readEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

   WSAEventSelect(m_socket, m_readEvent, FD_READ);
}

UDPReceive::~UDPReceive()
{
   closesocket(m_socket);
   CloseHandle(m_readEvent);
}


They aren't created every time you call send or receive.

So in your NetBoard.h file just add something like

Code: Select all
private:
SMUDP::UDPSend udpSend;
SMUDP::UDPReceive udpReceive;


The sockets will automatically be created when CNetBoard is created, and automatically be destroyed when CNetBoard destructor is called.

INADDR_ANY when listening on a socket means that any IP can connect to you. You can filter IPs, so for example if you only want localhost connections you would do this
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
Ian
 
Posts: 1325
Joined: Tue Feb 23, 2016 9:23 am

Re: Network code

Postby Ian » Mon Jan 01, 2018 4:28 am

Spindizzi,
I had a thought .. Currently sending will block until all the data has been received at the other end.
I could give it a thread and make it return immediately. Would that help? I am not sure how the sending/receiving sync works between separate instances.
Ian
 
Posts: 1325
Joined: Tue Feb 23, 2016 9:23 am

Re: Network code

Postby Spindizzi » Tue Jan 02, 2018 3:11 am

firstly, thanks for the explanations above
I had to read badly, I do not know how I made my way, :oops:

Nothing is better than a check :) Will try it
The little snippet code, I've sent you, is the way that it would work : recv is blocking, but not a blocking send

Originaly, the send procedure simply sends data (parameters : pointer where the data start and size of datas), and the recv procedure simply waits for datas coming in (blocking one) (parameters : pointer where the datas must go and data size, can return the size of data received if needed for compare). There is no real sync (the 1st packet is the sync). The real sync is a different process, no real ideas for now
Spindizzi
 
Posts: 96
Joined: Thu Nov 17, 2016 8:55 am
Location: France

Re: Network code

Postby Ian » Tue Jan 02, 2018 4:42 am

TCP send will block if too much data is sent.
UDP send I don't think blocks, the packets just get lost :p

The current code should always return the correct size that was sent.

if (packet.currentID + 1 == packet.totalIDs) {
break; // reached the end
}


The packets are given IDs, and when the total are sent it returns. But you managed to break the code by letting it time out :p In that case Send() would return false.
Ian
 
Posts: 1325
Joined: Tue Feb 23, 2016 9:23 am

Re: Network code

Postby Ian » Tue Jan 02, 2018 11:45 am

Spindizzi,
I wrote a non blocking send version.
Basically it copies all the data before sending, and then sends in a different thread. So the function returns immediately without blocking.

example code

Code: Select all
int _tmain(int argc, _TCHAR* argv[])
{
   //=====================
   UDPSend      udpSend;
   UDPReceive   udpReceive;
   //=====================

   udpReceive.Bind(6000);      // must bind to required socket

   std::vector<UINT8> testData;
   testData.resize(104800);

   for (auto &c : testData) {
      c = rand() % 255;
   }

   while (1) {

      udpSend.SendAsync("127.0.0.1", 6000, testData.size(), (const char*)testData.data(), 2000);   // non blocking returns immediately, will send in a separate thread

      auto data = udpReceive.ReadData(2000);                                          // blocking call
      // make sure data.size() > 0 because it could potentially be 0 for a timeout
      printf("Data size received: %i bytes\n", (int)data.size());
   }

   system("pause");

   return 0;
}
Attachments
ConsoleApplication1.zip
(19.04 KiB) Downloaded 8 times
Ian
 
Posts: 1325
Joined: Tue Feb 23, 2016 9:23 am

Re: Network code

Postby Spindizzi » Wed Jan 03, 2018 6:26 am

Hello,
Ian, faster than light, incredible , lol
I've checked with your new code, it's definitively better.
And now working through local network :)
However, I've not tested the amount of datas received as you recommend, so I've raised the timeout else I've got sync trouble
I've always got error when I quit (but not always). Do I forgot to free something or timeout too long or release threads. Need investigations
++
Spindizzi
 
Posts: 96
Joined: Thu Nov 17, 2016 8:55 am
Location: France

Re: Network code

Postby Ian » Wed Jan 03, 2018 6:36 am

What error do you get on quitting ? :)
Ian
 
Posts: 1325
Joined: Tue Feb 23, 2016 9:23 am

Re: Network code

Postby Spindizzi » Wed Jan 03, 2018 9:05 am

has stopped working in normal build but in debug mode:
Exception levée : violation d'accès en lecture. (read access violation)
**header_from_block**(...) retournée 0xFFFFFFFFFFFFFFE3. a eu lieu 

in debug_heap.cpp (windows c++ file, not supermodel)
in this methode
extern "C" __declspec(noinline) void __cdecl _free_dbg(void* const block, int const block_use)
Spindizzi
 
Posts: 96
Joined: Thu Nov 17, 2016 8:55 am
Location: France

PreviousNext

Return to The Dark Room

Who is online

Users browsing this forum: No registered users and 3 guests