I am going to create multiple synchronous clients . I need some explanation about below code.
When i am creating a socket like below and call connect what is happening at network level.
I believe when we create a socket and call connect, a TCP/IP connection a tunnel made between client socket and server socket.
Once this sender(socket) connect with server ,that client & server will have a unique tunnel between them.
if i create another client it will have another unique tunnel between them.
In case if we got an error, that the client is not connected, always we should reconnect using existing socket(sender) then we will access the same data/connection that we had.
And we should not create a new socket then we will have a new tunnel and we will lost the previous connection and data.
Socket sender = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp );
sender.Connect(remoteEndpoint)
Please clarify if i am wrong.
What you call tunnel is really called a connection. Broken connections cannot be revived. Data loss is to be expected.
When you reuse an existing socket object to connect again you are creating a new connection. Reusing socket objects is not recommended (by me) because it is confusing.
Note, that TCP does not know what a socket is. The spec does not contain that word. Sockets are OS-level things.
Related
I'm using Socket with following configuration to receive multicast packets and the code is working properly.
socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socket.Bind(bindPoint);
socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(multicastAddress, IPAddress.Any));
socket.ReceiveTimeout = 1000;
But after disabling the network connection from Control Panel and enabling, the socket cannot receive the multicast data. I can see the packets with Wireshark. I tried closing the socket, resetting he socket but restarting is the only solution I came up with. The application will be used in an environment where the user typically remove the ethernet cable and plug another one.
Initially I was using UdpClient but the same problem persists on that too. The operating system is Windows 7 and I use .NET 4.5.2.
After disabling a network connection, Windows automatically uses another connection if you have one (virtual host etc.). After enabling the previous connection, the application doesn't use the correct connection since there were no interface selection made. Disabling other connections or specifying the interface solves the problem.
Most of the examples online are examples of a multithreaded tcp server, whereby the server listens for multiple incoming connections from the client.
What I'm looking for is for the "server", to initiate the connections. If I have 100 devices (all different IP address of course), my server will have to make 100 individual connections to each device and receive data from the devices.
This is how I would make my connection to a device
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true);
_socket.SendTimeout = 2000;
_socket.ReceiveTimeout = 2000;
_socket.Connect(new IPEndPoint(IPAddress, TCPPort));
But I would like to know if there's any component out there, that would fulfill the following
establish as many tcp connections as I want to the devices
receive & send data through the connection
handle tcp timeouts/disconnects/etc & re-establish connection to the IP
If there aren't any of such components, are there any tips as to how I should go about doing it? e.g., 1 connection per thread, or how do I handle if the data is received in multiple packets, etc?
Any insights would be greatly appreciated
There are several existing components out there that you could use to achieve what you want. Checkout http://www.networkcomms.net and http://code.google.com/p/lidgren-network-gen3/.
Having said that people always prefer to add that there is nothing stopping you writing everything from scratch yourself as per the example you give.
Disclaimer: I'm a developer for NetworkComms.Net.
This is my listening function and connection function
Socket Listen
public void Listen(){
IPEndPoint ep = new IPEndPoint(IPAddress.Any, PortNumber);
Listen.Bind(ep);
Listen.Listen(10);
Listen.BeginAccept(new AsyncCallback(NewConnection), null);}
public void NewConnection(IAsyncResult asyn)
{
Socket Accepted = Listen.EndAccept(asyn);
Listen.BeginAccept(new AsyncCallback(NewConnection), null);
SomeFunction(Accepted);
}
the code works fine and there is no problem - I traced the code to see how to work with different clients and I understand the flow. However, I don't understand how can 1 socket serve different clients. Does it time multiplex between the clients over the socket?
I read on MSDN that Accepted in my code can be only used for the established connection and can't be used any further - that part I don't understand. What actually happens when the client tries to connect to the server socket? Does EndAccept return a totally different socket with different port to establish the connection and keep listening with the same socket to accept more requests at the same time?
What you've said is basically correct, based on my understanding. The Accepted socket is not the same as Listen. After you EndAccept, you can kick off another BeginAccept async call with your listen socket, and you can use the newly created socket to communicate with your remote peer.
To verify, you can check the local port of the listen socket and the connected socket; they should be different.
So ideally, I am looking for a way to unite TCP and UDP on the server and manage both these connections under individual client threads. Currently, I am wondering if it is possible to accept a TCP connection and set up UDP communication from that.
Here is my ideal setup:
Client connects on TCP to server via TCPClient.connect()
Server accepts TCP connection via TCPListener
when server accepts TCP connection, it also gets the IPEndpoint from the TCP connection
and uses that to begin UDP communcation with:
serverUDPSocket.BeginReceiveFrom (byteData, 0, 1024,
SocketFlags.None, ref (Endpoint)ThatIPEndpointThatIJustMentioned,
new AsyncCallback(client.receiveUDP),
(Endpoint)ThatIPEndpointThatIJustMentioned);
^so this is where I am running into a little bit of a theoretical issue. From my understanding, the endpoints for TCP and UDP would be formatted differently. How can I resolve this issue? I would like to avoid having the client connect to UDP on a separate thread and then uniting these threads under a single managing class.
EDIT:
Here is the code that I am trying to implement:
//Listening for TCP
TcpClient newclient = listenTCP.AcceptTcpClient(); //Accept the client
Client clientr = new Client(newclient); //Create a new Client class to manage the connection
clientr.actionThread = new Thread(clientr.action); //This thread manages the data flow from the client via the TCP stream
clientr.actionThread.Start(clientr);
EndPoint endPoint = newclient.Client.RemoteEndPoint; //so this is the sketchy part. I am trying to get the endpoint from the TCP connection to set up a UDP "connection". I am unsure about the compatibility as UDP and TCP sockets are different.
UDPSocket.BeginReceiveFrom(new byte[1024],0,1024, SocketFlags.None,ref endPoint, new AsyncCallback(clientr.receiveUDP), null); //the AsyncCallBack is like the manager thread for UDP (same as in TCP)
clients.Add(clientr);
There is no problem in creating two listeners in one application, even if they use different protocol. I suppose you are not asking if you can do it on the same port (there is no point to do it anyway).
However listener is consuming thread so it need different thread if there is gui or some process to do in application (for example calculations meanwhile).
If you want to do everything in one thread you must first receive message from first listener, then setup second one. There is no possibility to setup 2 listeners in one thread at the same time because if you setup first listener it will consome whole thread waiting for message.
This was due to a lack of understanding of UDP on my part from the code level.
I ended up setting up the other method I described where it would accept initial UDP packets individually and then direct the communication (EndPoint + Message) towards a managing client class by comparing IP addresses.
Ok so I am new to socket programing and I'm making a game that is going to run from a server. I am going to try to be able to get a hundred clients to run off my server. Should I make one listener instance or one for every client? Also I've tried to make a hundred listeners all at 100 different ports but when I run my server I get an error while trying to start my listeners. The game is going to be a 3D RPG/MMORPG. Most of the game logic is in the clients though. What do you think that I should do?
If you are going to use TCP sockets, then you should create one listener socket (i.e. create a socket, bind it to a specific port and call Listen() on it). Then, when you Accept a connection and get another socket, which you use for receiving/sending data from/to client:
Socket socketListener;
// create listening socket
socketListener = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
IPEndPoint ipLocal = new IPEndPoint(IPAddress.Any, 30120); // use port 30120
//bind to local IP Address.
socketListener.Bind(ipLocal);
//start listening
socketListener.Listen(4);
while (true) // loop that accepts client connections
{
Socket socketWorker = socketListener.Accept();
HandleClientConnection(socketWorker); // your routine where you communicate with a client
}
Also, consider using sockets in asynchronous mode, that will be more efficient in terms of performance.
You only ever have one listener per server endpoint. The listener will then create a connection for the client that uses a different port. It is this connection you actually use for communication.