I am writing socket client for IO device, which is the tcp server. I am able co connect and listen for data which the server periodically sends. But from time to time, I need to send some instruction to the server and read its response.
What is the proper way to handle this task, to be able listening for incoming data and after instruction is sent, receive response and to know, witch part of received data the response is?
What if device is sending data, while I need to send data to device? how can I dispatch such traffic? Do I need one thread to read and one for writing? Is it possible to handle this using single thread per device (there will be up to hundreds of devices connected)?
I am using Socket.Receive and Socket.Send methods.
What is the proper way to handle this task, to be able listening for
incoming data and after instruction is sent, receive response and to
know, witch part of received data the response is?
The protocol must support this. When you send data it is unclear when it is going to be received. The protocol must allow you to differentiate between normal data and a response. You could prepend a header to each message that has a boolean field indicating this.
What if device is sending data, while I need to send data to device?
You can send and receive on the same socket concurrently. This is not a problem. You would usually have on thread for reading. You can write on demand. No need for a thread dedicated to that.
there will be up to hundreds of devices connected
This means you need to have hundreds of reads outstanding. This is doable with one thread per socket. On the other hand this starts to be a good use case for async IO. Find out how to use async/await with sockets. If async/await is not available to you because you are on VS2010 use one of the other ways of achieving async IO with sockets.
Related
I am currently on a personal project for learning purposes. I want to make a connection over UDP, for application such as games. Each datagram sent has a specific header that indicates which "logic" channel it belongs to - for example, channel 0 is just like UDP with the extra header overhead, and channel 1 uses more headers to bring some extra reliability. The channels objective is to "automatically" separate messages into logic groups, up to a specific amount.
In my current code, there is a simple loop in a separate thread that handles sending and receiving:
// This is pseudo code
public void Tick() {
if(Socket.Poll) {
do {
ReadMessage();
} while(Socket.Available > 0)
}
SendQueuedOutgoingMessages();
}
Though this works on an ideal world, I have this feeling that this logic fails when there are too many incoming or outgoing messages. Is it possible to use the same socket to simultaneously send and receive messages (i.e send and receive are asynchronous or in different threads)? Even if it is possible, would it be better if I simply used two or more UDP sockets (or mix TCP and UDP sockets, if I need reliability), having specially maintainability in mind?
The most direct alternative I can think around this would be to use a scheduling algorithm to control how many messages to read and send, by means of queue sizes or other factors, but this feels poor and inflexible in this situation.
Edit: Adding more information about the code.
The Tick() method is set to be called a specific amount of times per second if it immediately returns. For example, 30 times per second if no new in or out messages exists, and less if it needs some time to send or receive data. I've used blocking ReceiveFrom and SendTo methods as to avoid busy waiting or calls such as Sleep(0).
Though I immediately treat incoming messages, I use an outgoing messages queue to help with the channels idea - each channel has its own priority down to 'no priority', affecting its bandwidth share over time in smooth and busy moments.
Whether or not using 2 sockets for receiving and sending separately, or just a single one depends on the situation. If you are going to send a lot of messages, and even if you are on a dedicated thread, the socket might block if the outgoing queue that is used by the socket becomes full.
There are several solutions to this problem. Using 2 sockets and 2 distinct threads is one of them, using select in combination with asynchronous sockets is another. The point is that you don't want to stop receiving just because a send might block.
Each of these possible solutions have their own complexity.
The select api is meant to check if for a certain socket there is something to receive, but you can also use it to detect if a socket becomes writable again. You need a socket option to put the socket in non blocking state and you need to check for E_WOULDBLOCK return codes with each send. If so the send has failed and you have to queue the message yourself.
You don't really send and receive at the same time, it is sequentially. You use select to check if a socket is writable and readible by using 2 bitmasks manipulated with the fd_set api. You can use select even on multiple sockets at once. Then if select, which is a blocking call, returns, you can check each individual bit to check what actions needs to be performed.
The reason why a send can block, if a socket is not put in nonblocking state is that the output queue of the socket can be full. If the socket is blocking, it would simply wait for the queue to become ready again. But during that wait, you cannot receive anything on that same socket. This is the very reason why you need non blocking sockets and the select api, in combination with some kind of queueing mechanism yourself.
Why not simply the standard read loop setup?
while (true)
ReadMessage();
There is no scheduling or throttling necessary. It is not necessary to know whether a packet is ready or not.
You can read and write simultaneously on the same UDP socket.
There is no need for an outgoing queue, either. Just send.
I'm developing an embedded system that connects to a PC over ethernet using TCP sockets. The PC will be the TCP client, and the embedded system the server. If I understand it correctly, the classical communication model is that the client sends some data to the server, and the server responds every time. The server never initiates communication.
What I'd like to do is send commands from the PC to the embedded system, without corresponding responses. The embedded system will then execute the tasks described by the commands. If the embedded system has an error, or has some status message to report back, it will send these back, without being polled by the PC.
I've figured out everything but the receiving on the PC side. I'm programming the PC app in C#.net Can I set up a callback that fires whenever data has been received on the socket? Every example I've seen uses the receive method in a blocking fashion.
You can use asynchronous I/O on the socket stream. This is almost exactly what you're asking for - you start a receive operation and give it a callback to call when the receive is complete.
Check out the BeginReceive/EndReceive functions.
More info here: http://msdn.microsoft.com/en-us/library/bbx2eya8.aspx
The long and short of this is yes, of course.
What you want to do is fire up a new thread for each client that connects that then raises events on an event/command thread. You're under no obligation to respond to a request other than (and this is handled by your operating system's TCP/IP stack) sending ACK when you receive a packet (don't worry about this part the OS does this for you and it's part of what makes TCP/IP reliable).
As long as the socket is active you should be able to send back responses to the client, so basically you need to keep the socket active for as long as any command is running.
Here's a list of examples from Microsoft that should show you how to do this. http://msdn.microsoft.com/en-us/library/bew39x2a.aspx#Y0
I'm writing an instant messaging server in C# for learning purposes.
My question is whether I should use synchronous or asynchronous sockets to handle the IM clients. The goal is to handle as many clients as possible.
I'm not quite sure but as far as I know with async sockets the packets don't arrive in order which means when you send 2 chat messages and there is a delay/lag it's possible that the second one arrive before the first one. Is this right and if so, is there a way to solve this issue?
About sync sockets: Is synchronous sockets a good solution for many clients? Do I have to check every socket/connection in a loop if there are new packets? If so, isn't this quite slow?
Last question: Assume I want to implement a way to send files (e.g. images) through the protocol (which is a non-standard binary protocol btw), can I still send messages while uploading?
The goal is to handle as many clients as possible.
Async then. It scales a lot better.
I'm not quite sure but as far as I know with async sockets the packets don't arrive in order which means when you send 2 chat messages and there is a delay/lag it's possible that the second one arrive before the first one.
TCP guarantees that everything arrives in order.
Assume I want to implement a way to send files (e.g. images) through the protocol (which is a non-standard binary protocol btw), can I still send messages while uploading
I recommend that you use a separate connection for file transfers. Use the first connection to do a handshake (determine which port to use and specify file name etc). Then use Socket.SendFile on the new socket to transfer the file.
Everything #jgauffin said (i.e. TCP handles packet-order, async better for n(clients) > 1000).
Assume I want to implement a way to send files (e.g. images) through the protocol (which is a non-standard binary protocol btw), can I still send messages while uploading?
Your custom protocol has to be built to support this. If you write a 8MB packet to the Socket, you won't be able to write anything else using that socket until the 8MB are sent. Instead, use upload-chunks of smaller size so that other packets have the chance to go over the pipe as well.
[UPLOAD id=123 START length=8012389]
[UPLOAD id=123 PART chunk=1 length=2048 data=...]
[UPLOAD id=123 PART chunk=2 length=2048 data=...]
[MESSAGE to="foo#example.com" text="Hi"]
[UPLOAD id=123 PART chunk=3 length=2048 data=...]
// ...
[UPLOAD id=123 COMPLETE checksum=0xdeadbeef]
The difference between an async approach and a sync approach is more about the difference between non-blocking and blocking io. With both approaches, the data is delivered in the same order that it has been transmitted. However, you don't block while you wait for an async call to complete, so you can start transmitting to all of your clients, before any of the individual communications has finished writing to the socket (which is why typically it would be the approach followed by servers).
If you go down the sync route, you block until each transmission / receive operation has completed, which means you may require need to run multiple threads to handle the clients.
As far as uploading an image at the same time as sending messages, you may want to handle that down a different pipe connection between the client/server so that it doesn't cause a blockage.
My program uses sockets for inter-process communication. There is one server listening on a socket port(B) on localhost waiting for a list of TCP clients to connect. And on the other end of the server is another a socket(A) that sends out data to internet. The server is designed to take everything the TCP clients send him and forward to a server on the internet. My question is if two of the TCP clients happened to send data at the same time, is this going to be a problem for the server's outgoing socket(A)?
Thanks
The MSDN docs recommend that you use BeginSend and EndSend if multiple threads will be using the same socket to transmit data.
So I would suggest that you either use those methods or write outgoing data to a synchronized queue, from which a single thread will then pick data off of the queue and send it over socket(A)
You don't describe how you multiplex the traffic of multiple client streams onto a single outgoing stream. Just arbitrarily putting chunks of client traffic into the stream is guaranteed not the work. The receiving end on the opposite end of the intertube will have no idea what bytes belong to what conversation.
I'd recommend you focus on the opposite end first. What machine is out there, what does it do, what does it need to know about the multiple clients at the local end.
What makes more sense?
use one socket to send and receive data to/from a embedded hardware device
use one socket to send data and separate socket to read data
Communication is not very intensive but the important point is to receive data as fast as possible. Application works under Windows XP and up.
Sockets were designed for two way communication, so most likely the developers of the embedded device didn't design their system to work off two sockets.
I have some experience working with embedded hardware and I've seen them work various ways:
Device connects to your application and starts streaming data via UDP
In this scenario I've seen up to three sockets in play. One TCP listening socket that accepts a connection from the embedded device. The embedded device then sends through some connection parameters, such as how quickly it's going to send you the data. The embedded device then starts streaming data via upd. Once you've received the data you send a message down a second upd socket to say "I got that one". The device then starts streaming the next bit of data (again via upd). This then continues ad infinitum. I've seen variations where the initial TCP connection is skipped and device just constantly stream data.
Request/Response
How many sockets you'll need here depends on who's making the initial connection, as that'll determine who needs the listening socket. Since you're making the initial connection, I'll use that. This is the more connection oriented scenario. Here you make a connection to the device and request some data, the device then sends you the response to that data. In this scenarioyou can only use one socket. As the device will respond to each request on the socket it was received.
So to answer you question "What makes more sense?", it completely depends on the design of your embedded device. If it's responding on the same socket as you're requesting, the answer is simple as only one socket is possible. Streaming devices via upd should give better performance with two sockets, but again only if your device supports it.
As for the second part of your question, "to receive data as fast as possible.", that's easy go asynchronous. Here are some excellent blogs on asynchronous socket programming:
.NET Sockets - Two Way - Single Client (C# Source Code - Included)
.NET Sockets in Two Directions with Multiple Client Support (C# Source Code Included)
If you're using a custom/third party protocol to communicate with the device you can't go wrong having a read through these either:
How to Transfer Fixed Sized Data With Async Sockets
Part 2: How to Transfer Variable Length Messages With Async Sockets
Im no expert but is there any downside to just using one socket?
It can already send and receive and my guess is that you end up getting more overhead if you have one socket for reading and one for sending...