Following on this question: Connect to Windows app with WebRequest
, I decided to implement a simple web server type thing on my client app to receive the webrequest's.
Basically on the client app I have a listening socket and when it receives a connection it does something with the data and then returns a result.
Receiving the data actually works, but once I have processed it I need to send a result back to the phone which send the webrequest.
I tried with the code below and although it does return the data(for instance if i goto the address in firefox it displays the success message) it never gets back to the phone. I dont know where it is going wrong.
if (mySocket.Connected)
{
if ((numBytes = mySocket.Send(bSendData, bSendData.Length, 0)) == -1)
listBox1.Items.Add("Socket Error cannot Send Packet");
}
and mySocket is the original socket that I received the connection on.
Is there a specific way I need to return the result? The callback even on the phone isnt even firing. But I think I am sending back the data correctly as a webbrowser does get the response.
Thanks!
You need to either specify the content length in the response, or close the connection after you've sent it. Otherwise the phone won't know that the response has been completed.
That may not be the problem, but it seems like a pretty likely candidate.
Related
I am a junior programmer and it is my first time building a WebSocket application in C#.
I have been following the tutorial from this page:
https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_server
By sending messages from the client to the server, everything works well. However, I want to have a bidirectional connection, so that the server could send messages back to the client in order to see them in the browser.
I have tried the following method, by adding the following lines to the server code:
byte[] tosend = Encoding.ASCII.GetBytes("Message received by server");
stream.Write(tosend, 0, tosend.Length);
I thought the client would receive this message but unfortunately, it return an undefined error and closes the connection.
Could you explain why this method of sedning messages doesn't work and maybe give me a few suggestions?
Thanks!
Basically the title... I'd like to have same feedback on weather NamedPipeServerStream object successfully received a value. This is the starting code:
static void Main(string[] args){
Console.WriteLine("Client running!");
NamedPipeClientStream npc = new NamedPipeClientStream("somename");
npc.Connect();
// npc.WriteTimeout = 1000; does not work, says it is not supported for this stream
byte[] message = Encoding.UTF8.GetBytes("Message");
npc.Write(message);
int response = npc.ReadByte();
Console.WriteLine("response; "+response);
}
I've implemented a small echo message from the NamedPipeServerStream on every read. I imagine I could add some async timeout to check if npc.ReadByte(); did return a value in lets say 200ms. Similar to how TCP packets are ACKed.
Is there a better way of inspecting if namedPipeClientStream.Write() was successful?
I'd like to have same feedback on weather NamedPipeServerStream object successfully received a value
The only way to know for sure that the data you sent was received and successfully processed by the client at the remote endpoint, is for your own application protocol to include such acknowledgements.
As a general rule, you can assume that if your send operations are completing successfully, the connection remains viable and the remote endpoint is getting the data. If something happens to the connection, you'll eventually get an error while sending data.
However, this assumption only goes so far. Network I/O is buffered, usually at several levels. Any of your send operations almost certainly involve doing nothing more than placing the data in a local buffer for the network layer. The method call for the operation will return as soon as the data has been buffered, without regard for whether the remote endpoint has received it (and in fact, almost never will have by the time your call returns).
So if and when such a call throws an exception or otherwise reports an error, it's entirely possible that some of the previously sent data has also been lost in transit.
How best to address this possibility depends on what you're trying to do. But in general, you should not worry about it at all. It will typically not matter if a specific transmission has been received. As long as you can continue transmitting without error, the connection is fine, and asking for acknowledgement is just unnecessary overhead.
If you want to handle the case where an error occurs, invalidating the connection, forcing you to retry, and you want to make the broader operation resumable (e.g. you're streaming some data to the remote endpoint and want to ensure all of the data has been received, without having to resend data that has already been received), then you should build into your application protocol the ability to resume, where on reconnecting the remote endpoint reports the number of bytes it's received so far, or the most recent message ID, or whatever it is your application protocol would need to understand where it needs to start sending again.
See also this very closely-related question (arguably maybe even an actual duplicate…though it doesn't mention named pipes specifically, pretty much all network I/O will involve similar issues):
Does TcpClient write method guarantees the data are delivered to server?
There's a good answer there, as well as links to even more useful Q&A in that answer.
I have basically implemented this asynchronous server socket example (and the corresponding client). Using it, I can respond to the client if I follow the example exactly, i.e., if the call to Send() the response is in the ReadCallback() method.
If, however, I try and send a response outside of here, i.e., in a callback that I've attached to my message processing routine (running in a different thread), I get this error, saying the Socket is not connected. If I try and send a response somewhere else in the Server code, say in the while(true) loop that's listening to incoming connections, I get the same error.
Am I missing something fundamental here?
Edit:
Ok, so I read Two-way communication in socket programming using C, and I now think, according to that answer, that I have to modify the example I linked to so that I reply to the server on the socket returned by the accept process. My goal is to be able to call Send() outside of the receive callback, say from Main(), after the client and server are connected.
Please can someone suggest how I modify the example to achieve what I want? I'm getting thoroughly confused about this, and don't want to create a separate stream if I don't need to (which according to the question I posted, I don't need to...).
If you want to keep the connection open then would need to persist the handler variable as that is the open socket connection. Then whenever you want to send that connection a message you retrieve its socket and send.
Also, you obviously wouldn't call Shutdown() and Close() on the handler variable.
For a school assignment we have to make a client server chat program in C#. I have never done any networking in the past before so its very confusing for me. I read a book on C# networking, and I was able to make a very basic chat that works using binary readers and writers and a TCP socket. However for the assignment I have to make the client list all connected users. Now, how would I make it so that the client only reads the stream for a list when someone disconnects or connects on the server. I could make it so that the clients is always downloading a new list, but I feel that's a lot of redundant data being sent.
On a side note, I'm confused with how the client/server knows what the data in the stream is. So far I only have a string being sent through the stream which represents a message. Is there a way to attach some sort of signature or something to the data being sent so that the server or client knows that that specific data is the username or perhaps a message to be displayed.
Edit:
I'm having issues with the stream. I have a method that's running in its own thread that's always checking for information being sent. Its listing for both a string that's a message to display message and a List containing users connected. The problem is that the order of the data being sent isn't always in a consistent order. Sometimes the message is first, others the list is, and sometimes its only a message in the stream. Is there a way to tell what data is being read? Here is my client side listener.
private void incoming()
{
while (true)
{
try
{
string read = reader.ReadString();
if (read.Length > 0)
lbOutput.Items.Add(read);
lbUsers.Items.Clear();
List<string> users = (List<string>)binaryFormatter.Deserialize(stream);
foreach (string user in users)
lbUsers.Items.Add(user.ToString());
}
catch { lbOutput.Items.Add("Error reading the stream"); }
}
When a new client connects, it should send a message to the server to inform it that it has connected and ask it to store its name. Then the server can broadcast a message to all other clients with the new list (or just the name of the new client). Rough outline:
public class Server {
public void StartAcceptingConnections() {
while(true) {
// accept socket connection
// read new user name
foreach(Client cl in connectedClients) {
// send new user name to cl.Socket
}
}
}
}
In parallel, you are receiving messages from clients to be routed (I assume). When a client leaves, it will again send a disconnect message and the server can broadcast the change to the rest of the clients.
If you want to work with more than just bytes and strings, you can try to send entire object by serialization. Have a look at this tutorial: http://msdn.microsoft.com/en-us/magazine/cc301761.aspx.
Since you said it needs to be a client/server application, I would approach this using WCF with a duplex binding. This allows the service to send messages back to the client rather than just receive them (kind of like eventing).
An explanation can be found here:
http://msdn.microsoft.com/en-us/library/ms731064.aspx
If the solution did not have to be client/server, a more elegant solution could be to use a peer-to-peer approach where there is no server and all the clients communicate together in a kind of web. There are sample on the web showing how to exactly what you want in fact (not that I'm encouraging you to cheat...). For example
http://www.codeproject.com/KB/WCF/Chat_application_using_WC.aspx
We are trying to get image uploading working with TinyPic that tracks the progress of the upload. We used HttpWebRequest earlier but since that doesn't support tracking progress, we decided to try low level methods such as TcpClient.
The code when executed gets "stuck" in this line:
int networkBytesRead = networkStream.Read(buffer, 0, buffer.Length);
The code hangs there for more than one minute.
Please have a look at this code for the full class:
http://paste2.org/p/331631
Any input is appreciated.
Thanks,
McoreD from ZScreen
Usually this error is caused when client and server are not synchronized, that is may be the server is listening at the same time when client is sending data. may be you should send an empty line or something else, to give server know that he should send data.HttpWebRequest know about that is why he work so good:) You can try to record traffic by tcp snipper in case of HttpWebRequest and compare it with the traffic of NetworkStream