Does any one have an example for ReceiveFromAsync works with regard to UDP? i couldn't find any sample code. I can find a few TCP sample but msdn say 'The ReceiveFromAsync method is used primarily to receive data on a connectionless socket'.
Thanks,
Nick
Perhaps it might be easier to use UdpClient's async BeginReceive() method?
http://msdn.microsoft.com/en-us/library/system.net.sockets.udpclient.beginreceive.aspx
If performance is not a concern, a quick and simple approach could be UdpClient's ReceiveAsync method:
https://msdn.microsoft.com/de-de/library/system.net.sockets.udpclient.receiveasync(v=vs.110).aspx
Then you can use the result (UdpReceiveResult) to filter for a specific remote endpoint where you want to receive data from. Here is a small example:
private async void ReceiveBytesAsync(IPEndPoint filter)
{
UdpReceiveResult receivedBytes = await this._udpClient.ReceiveAsync();
if (filter != null)
{
if (receivedBytes.RemoteEndPoint.Address.Equals(filter.Address) &&
(receivedBytes.RemoteEndPoint.Port.Equals(filter.Port)))
{
// process received data
}
}
}
Related
I've been searching quite a bit on this topic, but I think I'm not using the right words for searching any of this stuff, because I've not found an answer yet.
I'm looking for a way to make a process wait for a (specific) response of an external source.
In more detail, in a standard socket connection, I ask my remote endpoint for a certain value via a socket.send, how can I "catch" their reply? The idea that I already had was to send some sort of identifier along to determine what request this belongs to.
Is there a way to efficiently achieve this? (Performance is rather important). I'm currently using .NET2.0 if that's relevant information.
Some example code:
public void AskForReply()
{
//Send to connected endpoint
}
public void ReceiveReply(IAsyncResult response)
{
//Do stuff with the response
}
I've been working out several ideas in my head. But they all feel really messy and not very efficient. Is there a design pattern for this? Are there standards for this behavior?
And help is greatly appreciated!
For anyone who runs into a similar problem, I have found a way to make an asynchronous call synchronous (which is essentially what you are trying to achieve).
EventWaitHandle waitHandler;
string replyMessage;
void string AskForReply()
{
//Already requesting something...
if(waitHandler != null) { return; }
waitHandler = new EventWaitHandle(false, EventResetMode.AutoReset);
//Send a request to a remote service
waitHandler.WaitOne(timeout);
//Will reply null (or the default value) if the timeout passes.
return replyMessage;
}
void ReceiveReply(string message)
{
//We never asked for a reply? (Optional)
if (waitHandler != null) { return; }
replyMessage = message;
//Process your reply
waitHandler.Set();
waitHandler = null;
}
It's probably a good idea to put the EventWaitHandle and the reply message in a class for better and cleaner management. You can then even put this object in a dictionary along with a key that you can use handle multiple requests at once (do keep in mind they are synchronous and will block your thread until the timeout or the waithandle is set).
Could someone explain why i am getting Timeouts are not supported on this stream. error.
If i use my code like this everythings fine. My sockets connects to server adn retreives info. (This method was like dummy cause the connection was happening for one server and at the start of everything)
private async Task Update()
{
while (true)
{
server = Ips.First();
if (server.Map != sq.map || server.Name != sq.name || server.Players != sq.players)
{
return;
}
}
}
While in real app i need to query a lot of servers. So i try something like this ( cause i'm noob and cant figure out a better way )
foreach (var server in Ips)
{
sq.Connect(new Windows.Networking.HostName(server.Ip), server.Port);
if (server.Map != sq.map || server.Name != sq.name || server.Players != sq.players)
{
return;
}
}
And that's where i get Timeouts are not supported on this stream error. Can someone explain why and maybe tell me where should i look in too?
My error comes in first line of this method:
(Stream streamIn = args.GetDataStream().AsStreamForRead();)
private async void Socket_MessageReceived(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs args)
{
Stream streamIn = args.GetDataStream().AsStreamForRead();
StreamReader reader = new StreamReader(streamIn);
string message = await reader.ReadToEndAsync();
byte[] packet = System.Text.Encoding.ASCII.GetBytes(message);
Parser parser = new Parser(packet);
But why does the first method work?
The main difference between your first code block and the second one is sq.Connect(new Windows.Networking.HostName(server.Ip), server.Port);, base on your code, it is possible that
you only connect to Ips.First(), and the code run to "return" to jump out of the "foreach".
you establish two(or more) connections until the code run to "return".
I don't know what is your sq, and there is no Connect(hostname, serverport) method in DatagramSocket class, there is only a similar method but an aysnc one: DatagramSocket.ConnectAsync(HostName, String) | connectAsync(HostName, String) method.
Mapping to the two possibilities I listed up:
if the code in "foreach" only run one time (means Ips.First() connected), then the difference between two code block is you established a connection in the second code, this could be a reason.
for the second possibility, I assume that you are using ConnectAsync method actually, then sq is c sq = new DatagramSocket();, and it is connected to several servers using one DatagramSocket. But ConnectAsync method is for communicate with a single remote endpoint, so I think it could also be the reason here.
While in real app i need to query a lot of servers.
I think for your scenario, it's better not using connections, you can bind your DatagramSocket to a local port, and join a DatagramSocket object to a multicast group. You can refer to the official DatagramSocket sample, the scenario 5 is for multicast and broadcast, you can take a look.
If you have any problems here, please leave a comment.
I'm trying to read data from SerialPort and what I'm now trying to do is to poll the SerialPort every 100ms and see if it contains any remaining data.
public static async Task<string> ReadRemaining(SerialPort port)
{
int prevBytesToRead = 0;
await Task.Delay(100);
while (prevBytesToRead != port.BytesToRead || port.BytesToRead == 0)
{
prevBytesToRead = port.BytesToRead;
await Task.Delay(100);
}
return port.ReadExisting();
}
I feel this is very inefficient. Is there a better way?
You already are using the BytesToRead property, which is not really the best approach1, but I guess it is working for you.
You appear to be asking for a prediction of the future, you're asking about data that hasn't yet been sent from the other device. There's no way for the serial port to know that. Perhaps based on your application protocol, the other device tells you when it is done sending (end of message marker) or perhaps told you how long the message would be.
You have to figure out how to rephrase the question so it doesn't require prophesying the future.
1The clean way to use serial ports and C# async is to call port.BaseStream.ReadAsync. Make sure the timeouts are set properly. Under Win32 timeouts you can detect gaps in the stream which often correspond to message boundaries, sadly .NET SerialPort doesn't allow that. But you still can find a better value for the ReadTimeout property than the default.
I have been reading a lot about ThreadPools, Tasks, and Threads. After awhile I got pretty confused with the whole thing. Lots of people saying negative/positive things about each... Maybe someone can help me find a solution for my problem. I created a simple diagram here to get my point across better.
Basically on the left is a list of 5 strings (URL's) that need to be processed. In the center is just my idea of a handler that has 2 events to track progress. Inside that handler it takes all 5 URL's creates separate tasks for them, shown in blue. Once each one complete I want each one to return the webpage results to the handler. When they have all returned a value I want the OnComplete to be called and all this information passed back to the main thread.
Hopefully you can understand what I am trying to do. Thanks in advance for anyone who would like to help!
Update
I have taken your suggestions and put them to use. But I still have a few questions. Here is the code I have built, mind it is not build proof, just a concept to see if I'm going in the right direction. Please read the comments, I had included my questions on how to proceed in there. Thank you for all who took interest in my question so far.
public List<String> ProcessList (string[] URLs)
{
List<string> data = new List<string>();
for(int i = 0; i < URLs.Length - 1; i++)
{
//not sure how to do this now??
//I want only 10 HttpWebRequest running at once.
//Also I want this method to block until all the URL data has been returned.
}
return data;
}
private async Task<string> GetURLData(string URL)
{
//First setup out web client
HttpWebRequest Request = GetWebRequest(URL);
//
//Check if the client holds a value. (There were no errors)
if (Request != null)
{
//GetCouponsAsync will return to the calling function and resumes
//here when GetResponse is complete.
WebResponse Response = await Request.GetResponseAsync();
//
//Setup our Stream to read the reply
Stream ResponseStream = Response.GetResponseStream();
//return the reply string here...
}
}
As #fendorio and #ps2goat pointed out async await is perfect for your scenario. Here is another msdn article
http://msdn.microsoft.com/en-us/library/hh300224.aspx
It seems to me that you are trying to replicate a webserver within a webserver.
Each web request starts its own thread in a webserver. As these requests can originate from anywhere that has access to the server, nothing but the server itself has access or the ability to manage them (in a clean way).
If you would like to handle requests and keep track of them like I believe you are asking, AJAX requests would be the best way to do this. This way you can leave the server to manage the threads and requests as it does best, but you can manage their progress and monitor them via JSON return results.
Look into jQuery.ajax for some ideas on how to do this.
To achieve the above mentioned functionality in a simple way, I would prefer calling a BackgroundWorker for each of the tasks. You can keep track of the progress plus you get a notification upon task completion.
Another reason to choose this is that the mentioned tasks look like a back-end job and not tightly coupled with the UI.
Here's a MSDN link and this is the link for a cool tutorial.
Basically, I've written a windows phone 7 client, which is supposed to receive a very long string from the server. However, there seem to be some limitations on the phone networking code, and am having trouble figuring out how to do this. The following is the code I am using:
public string Receive()
{
string response = "Operation Timeout";
StringBuilder content = new StringBuilder();
// We are receiving over an established socket connection
if (_socket != null)
{
// Create SocketAsyncEventArgs context object
SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
socketEventArg.RemoteEndPoint = _socket.RemoteEndPoint;
// Setup the buffer to receive the data
socketEventArg.SetBuffer(new Byte[MAX_BUFFER_SIZE], 0, MAX_BUFFER_SIZE);
// Inline event handler for the Completed event.
// Note: This even handler was implemented inline in order to make this method self-contained.
socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e)
{
if (e.SocketError == SocketError.Success)
{
response = Encoding.UTF8.GetString(e.Buffer, e.Offset, e.BytesTransferred);
response = response.Trim('\0');
}
else
{
response = e.SocketError.ToString();
}
_clientDone.Set();
});
// Sets the state of the event to nonsignaled, causing threads to block
_clientDone.Reset();
// Make an asynchronous Receive request over the socket
_socket.ReceiveAsync(socketEventArg);
// Block the UI thread for a maximum of TIMEOUT_MILLISECONDS milliseconds.
// If no response comes back within this time then proceed
_clientDone.WaitOne(TIMEOUT_MILLISECONDS);
}
else
{
response = "Socket is not initialized";
}
return response;
}
As it stands, this will only accept the first N bytes of the message and return that... any help on how to do this would be greatly appreciated! Thanks!
Firstly, I would try to redesign your code to be appropriately async - working round the fact that WP7 doesn't offer synchronous IO by building your own isn't nearly as clean as embracing the asynchrony.
Secondly, you're assuming that you only need a single ReceiveAsync call to get the whole data. Assuming your using TCP, that's a stream-based protocol. You'll need to either add some sort of delimiter or length prefix, or keep reading until the other side closes the connection if that's the way your protocol works.
(Any reason you're not doing this with HTTP and WebClient or WebRequest, by the way?)
Firstly, I would try to redesign your code to be appropriately async - working round the fact that WP7 doesn't offer synchronous IO by building your own isn't nearly as clean as embracing the asynchrony.
Secondly, you're assuming that you only need a single ReceiveAsync call to get the whole data. Assuming your using TCP, that's a stream-based protocol. You'll need to either add some sort of delimiter or length prefix, or keep reading until the other side closes the connection if that's the way your protocol works.
(Any reason you're not doing this with HTTP and WebClient or WebRequest, by the way?)