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!
Related
I have a weird scenario and I'm not sure how to solve it.
I have a simple tcp chat server in nodejs and my clients are currently in native C#, and eventually will move to Unity. I have my own networking library which creates the TCP connection and handles messages etc, and works fine in some cases until it comes to disconnecting.
The server is running on an EC2 instance and I am loading two windows on my PC to test the multiple connections. When I close the window, I receive this error in the nodejs server console
Error: read ECONNRESET
at exports._errnoException (util.js:870:11)
at TCP.onread (net.js:544:26)
Which is fine, because this is the scenario where it works. I'm guessing this just means that the connection was abruptly closed (closing the window).
However problems arise when I instruct the socket to be shutdown.
I am porting my client to Unity and when closing the client, it does not produce this ECONNRESET error and the connection never closes abruptly (like I'd expect it to), so in this case I have to manually close the connection on the client which results in a different error.
Error: This socket has been ended by the other party
at Socket.writeAfterFIN [as write] (net.js:268:12)
at /opt/chat/chat.js:32:10
at Array.forEach (native)
at broadcast (/opt/chat/chat.js:31:10)
at Socket.<anonymous> (/opt/chat/chat.js:26:2)
at emitNone (events.js:72:20)
at Socket.emit (events.js:166:7)
at endReadableNT (_stream_readable.js:905:12)
at nextTickCallbackWith2Args (node.js:441:9)
at process._tickCallback (node.js:355:17)
When I receive this error on the server, the other connected clients can continue messaging the server, however they cannot receive messages from it.
My nodejs server was pulled from github here:
https://gist.github.com/creationix/707146
// Load the TCP Library
net = require('net');
// Keep track of the chat clients
var clients = [];
// Start a TCP Server
net.createServer(function (socket) {
// Identify this client
socket.name = socket.remoteAddress + ":" + socket.remotePort
// Put this new client in the list
clients.push(socket);
// Send a nice welcome message and announce
socket.write("Welcome " + socket.name + "\n");
broadcast(socket.name + " joined the chat\n", socket);
// Handle incoming messages from clients.
socket.on('data', function (data) {
broadcast(socket.name + "> " + data, socket);
});
// Remove the client from the list when it leaves
socket.on('end', function () {
clients.splice(clients.indexOf(socket), 1);
broadcast(socket.name + " left the chat.\n");
});
// Send a message to all clients
function broadcast(message, sender) {
clients.forEach(function (client) {
// Don't want to send it to sender
if (client === sender) return;
client.write(message);
});
// Log it to the server output too
process.stdout.write(message)
}
}).listen(5000);
// Put a friendly message on the terminal of the server.
console.log("Chat server running at port 5000\n");
Scenario
Let's assume we have CLIENT A on the left and CLIENT B on the right
On initial connection, they can both chat fine.
CLIENT B wishes to disconnect, and the code forces the disconnect by terminating the socket. The nodejs server receives the error "This socket has been ended by the other party" and broadcasts that this player has disconnected to CLIENT A
CLIENT A wishes to continue communicating, regardless that no one is connected. CLIENT A continues typing and sending messages, however the messages are not being received once CLIENT B has disconnected. However, the messages are indeed being sent to the server.
CLIENT A is NOT receiving his own messages.
CLIENT B wishes to reconnect to continue chatting and does so.
CLIENT A sends message 'hello'
CLIENT B sends message 'hello'
CLIENT B is seeing both messages, and experiencing a normal chat, however CLIENT A is not seeing any of the messages and is stuck on a blocking call trying to read data.
This is ONLY when I force the socket closed, and it works perfectly fine when I receive the ECONNRESET error. How can I replicate this error, or fix my issue?
EDIT
I have managed to reproduce the ECONNRESET error and now it works, but it still doesn't explain why it doesn't work with other errors.
The methods Close and GetStream().Close in C# TcpClient are not sufficient it seems to close a connection properly. Instead I had to access the socket directly and close that.
Closing the socket directly works in a native C# application but not in Unity.
To replicate this error in Unity I have to use
Shutdown(SocketShutdown.Receive);
I have a really weird issue with communication between server and client using UDP protocol. Client is written in Mono2x (I use Unity 3D as my client) and creates UdpClient class instance:
_udpClient = new UdpClient(9050);
_serverEP = new IPEndPoint(IPAddress.Parse(_serverIp), _serverPort);
My server is UWP application I want to run on Raspberry Pi that is using DatagramSocket:
_udpServer = new DatagramSocket();
_udpServer.MessageReceived += ClientCheck;
await _udpServer.BindServiceNameAsync(port.ToString());
I send data from client to server but with no luck. I checked with TCPView that data is send from my client application but never reaches the server. And now is the weird part. When I receive message from server first (I hardcode port to client), my client is able to send data with a success.
I am using same IPEndPoint to send data from client without any changes after receiving packet from server, it just starts working. Honestly, I have no idea what I could do wrong, so I will be thankful for any advice.
And now is the weird part. When I receive message from server first (I hardcode port to client), my client is able to send data with a success
This is a known issue which is filed based on this related question: https://stackoverflow.com/a/39767527/5254458
It includes the issue's description and temporary workaround.
The corresponding is team is investigating it and I can not guarantee that when the fix will be delivered.
Im building a multi client to server system using .Net for the client side and python for server side. Currently my python server socket simply echoes back the data sent to it without doing any extra processing:
from twisted.internet import reactor, protocol
class Echo(protocol.Protocol):
"""This is just about the simplest possible protocol"""
def dataReceived(self, data):
"As soon as any data is received, write it back."
self.transport.write(data)
print(str(data))
def main():
"""This runs the protocol on port 8000"""
factory = protocol.ServerFactory()
factory.protocol = Echo
reactor.listenTCP(8000,factory)
reactor.run()
# this only runs if the module was *not* imported
if __name__ == '__main__':
main()
Its built on the Twisted framework, and can be found on the examples page, at their website.
Im also using the Async TCP client for C# provided by MicroSoft found at:
https://msdn.microsoft.com/en-us/library/fx6588te%28v=vs.110%29.aspx
The problem is, the client sends the data successfully to the server - and the server receives it, and can echo it successfully, however the line:
self.transport.write(data)
Doesnt seem to send the data back correctly because the client never receives a reply back. Why is this happening? Is it a possible deadlock between reading streams?
I have created an Instant Messanger that allows communication between clients through a server.
The server stores the NetworkStream and username of the clients which are logged in, and the message sent from the client is used to ascertain to whom the server should route the message too.
The problem I am having is that the first two messages from one client to another works, e.g:
Client1 sends message to Client2
Server receives client1's message and routes to client2 (target)
Client2 Receives message (presents)
And vice vercia.
After the initial message is sent by client1, client2 does not receive messages from client1 ever again.
The problem I see is that the server does indeed receive the messages and seems to send it to the right stream, but the intended client doesn't receive it.
The receiving client in this situation, client2 cannot/does not receive messages, but can send messages and client1 does receive them.
If any more information is needed please let me know.
I can guarentee that the code I am using is accurate, the only thing I can think of is in the nature of the networkstream or tcpclient.
int accountThreadCount = 0;
while (accountThreadCount < login.newClientLogin.clientList.Count())
{
AccountThread newAccountThread = login.newClientLogin.clientList[accountThreadCount];
if (newAccountThread.username == comm.to)
{
Stream relayMessageStream = newAccountThread.tcpc.GetStream();
iff.Serialize(relayMessageStream, comm);
}
accountThreadCount++;
}
AccountThread stores, the TcpClient and username and other things.
Now assuming that this is working perfectly, as it is otherwise the first two wouldn't work. As I have already said above this is very peculiar to me, I have tried re-coding to no avail.
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.