An existing connection was forcibly closed by the remote host - UDP Issue

Started by
16 comments, last by hplus0603 5 years, 3 months ago

I'm just looking over your code...

Why are you mixing a tcpclient and udpsockets in the same netcode?

Advertisement
1 minute ago, Septopus said:

I'm just looking over your code...

Why are you mixing a tcpclient and udpsockets in the same netcode?

We were given a VERY bad tutorial on setting up UDP for our assignment and that is what it told us to do xD 

Well, this is a no-homework zone, so I'll keep being a bit terse I guess, lol. 

Start with that.  If you are trying to write UDP netcode, drop anything related to TCP.  It will only confuse you further.  TCP and UDP are different animals.  There are quite a few examples of functional UDP netcode, in (insert .net language of choice) on the nets.  Pick one and follow it as a guide.  ;)   You're very very close.

1 minute ago, Septopus said:

Well, this is a no-homework zone, so I'll keep being a bit terse I guess, lol. 

Start with that.  If you are trying to write UDP netcode, drop anything related to TCP.  It will only confuse you further.  TCP and UDP are different animals.  There are quite a few examples of functional UDP netcode, in (insert .net language of choice) on the nets.  Pick one and follow it as a guide.  ;)   You're very very close.

Prefer if you didn't since I've spend hours trying to get this working but fine xD 

Did you fix the improper call to Connect that I pointed out in the first answer?

Also, what is the UDPClient class, as opposed to the UDPSocket class? Both client and server should be able to use bare UDP sockets. And if you use a UDPClient, that should be on the client side, not the server side.

It seems to me that you haven't yet understood how Ethernet, IP, and UDP networking works on the wires, in the network cards, in the kernel, and in the API. Thus, you're trying to just mash buttons in the dark. That will never work.

 

What your client needs to do:

1) Find the server's IP address. This could be an argument to the program. You can resolve it using IPEndPoint.

2) Create a UDP socket. It shouldn't be bound or connected to any particular address/port.

3) Keep a receive request outstanding on the socket; when the receive request comes in, parse the packet, and issue a new receive request. Remember the IP address and port that the packet came in from, so you can respond to it! If you haven't received anything from the server for five seconds, assume that the server disconnected and stop the session.

4) On a timer of some sort, send an outgoing packet to the server, on your games well-defined port number, and on the server's IP address, depending on the state of the client (if not yet connected, send connection request; if in a game, send game input state; and so forth.)

 

What the server needs to do:

1) Create a UDP socket

2) Bind (not Connect) to the INADDR_ANY address (0.0.0.0) on the game's well-defined port number.

3) Always keep a read request active. When it completes, remember the IP address/port of the packet, and look up in a dictionary of clients. If client doesn't exist, create a new client and put in the dictionary. Handle each packet as it comes in, based on your known game state and the per-client state. Keep note of the last time you received data from the client.

4) On a timer or some sort, iterate through all the clients in your dictionary of clients, and send some kind of packet/update of game state to those clients. If some client hasn't sent anything to you for the last 5 seconds, assume the client disconnected and kick it.

 

You will note that some of those patterns are similar and can be re-used between client/server, but you don't have to do so right away -- it's probably easier to write them as separate things first, to make sure you keep the concerns of the two sides separated.

Remove anything from your code that doesn't look like what I suggested above. Or, better yet, start from an empty project, and build those bits of code from scratch, using MSDN documentation. When you need to import things like serialization or game code, move those files over into the new project. By building from scratch, you know what all the bits are doing, which will help you build a robust program overall.

 

enum Bool { True, False, FileNotFound };
On 12/26/2018 at 2:15 AM, hplus0603 said:

Did you fix the improper call to Connect that I pointed out in the first answer?

Also, what is the UDPClient class, as opposed to the UDPSocket class? Both client and server should be able to use bare UDP sockets. And if you use a UDPClient, that should be on the client side, not the server side.

It seems to me that you haven't yet understood how Ethernet, IP, and UDP networking works on the wires, in the network cards, in the kernel, and in the API. Thus, you're trying to just mash buttons in the dark. That will never work.

 

What your client needs to do:

1) Find the server's IP address. This could be an argument to the program. You can resolve it using IPEndPoint.

2) Create a UDP socket. It shouldn't be bound or connected to any particular address/port.

3) Keep a receive request outstanding on the socket; when the receive request comes in, parse the packet, and issue a new receive request. Remember the IP address and port that the packet came in from, so you can respond to it! If you haven't received anything from the server for five seconds, assume that the server disconnected and stop the session.

4) On a timer of some sort, send an outgoing packet to the server, on your games well-defined port number, and on the server's IP address, depending on the state of the client (if not yet connected, send connection request; if in a game, send game input state; and so forth.)

 

What the server needs to do:

1) Create a UDP socket

2) Bind (not Connect) to the INADDR_ANY address (0.0.0.0) on the game's well-defined port number.

3) Always keep a read request active. When it completes, remember the IP address/port of the packet, and look up in a dictionary of clients. If client doesn't exist, create a new client and put in the dictionary. Handle each packet as it comes in, based on your known game state and the per-client state. Keep note of the last time you received data from the client.

4) On a timer or some sort, iterate through all the clients in your dictionary of clients, and send some kind of packet/update of game state to those clients. If some client hasn't sent anything to you for the last 5 seconds, assume the client disconnected and kick it.

 

You will note that some of those patterns are similar and can be re-used between client/server, but you don't have to do so right away -- it's probably easier to write them as separate things first, to make sure you keep the concerns of the two sides separated.

Remove anything from your code that doesn't look like what I suggested above. Or, better yet, start from an empty project, and build those bits of code from scratch, using MSDN documentation. When you need to import things like serialization or game code, move those files over into the new project. By building from scratch, you know what all the bits are doing, which will help you build a robust program overall.

 

I actually fixed it just now and it was because of the simplest mistake... as it normally is.

image.png.b22383776da8076384c0bf0a4b5ac543.png

That line shouldn't be there. I removed it and everything worked perfectly.

You still have a bug in that you don't slice the incoming byte array to the size of the number of bytes you've received.

Thus, the memorystream may deserialize out from uninitialized or zero data in the byte array -- it thinks you always got 256 bytes.

This is the kind of bug that exploiters love to find in networked games; undefined behavior that lets them craft packets that makes the computer do things it wasn't intended to do.

enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement