I have a simple TCP server written in C#, pinging out data at a specified interval and receiving the data I have a NodeJS app.
I'm current sending the data from a NetworkStream like so:
private NetworkStream nwStream;
nwStream = clientMachine.GetStream();
nwStream.Write(buffer, 0, buffer.Length); // Inside a loop
And receiving it in NodeJS like:
client.on('data', (data) => {
Is there any way to emit a different event, other than data from my C# TCP server? Using Socket.io I can socket.emit('customEvent', someData) and receive it like socket.on('customEvent', receivedData) but I'm unsure if I can achieve this in C#.
I'm not working with Socket.io, the above is just an example of the behaviour I'd like to achieve.
If you're using raw sockets at both ends, you'll just have to design your own protocol that embeds a name into each logical frame... TCP sockets themselves don't have any such mechanism, nor do raw packets.
A typical / simple way of doing this might be something like:
{Event name, UTF8}\r\n{length, 4 bytes little endian integer}{payload, length bytes}
If your event name might include newline/linefeed, then you'd need to use the payload length/payload approach for the event name, too.
Socket.IO has it's own network protocol specified here. The encodeAsString(obj) function in 'socket.io-parser' may be what you're looking for.
Related
Hi I have a socket programming with C# Socket Server and C++ Socket Client.
Server I use Socket.Send(bytes[]) to send message
CPP Client side i use recv(socket,buffer,length,flags)
But in server if i send multiple messages concurrently on the client side i recieve all messages as concatenated.
for(int i=0;i<10;i++)
{
var bytes= GetBytes("msg"+i);
theSocket.Send(bytes);
}
C++ Socket CLient:
Thread.Start()
{
var msg = recv(theSocketClient,buffer,1024,0);
ProcessMessageFromSocket(msg);
}
Expected is:
process msg1 then
Process msg2... Process msg10
Actual:
processMessage(msg1msg2msg3...msg10 );
What i am missing?
my attempts to fix this:
1. C# NetworkStream.Flush() -- Even after this it gives me concatenated strings
2. CPP Everytime after finishing the read i erase the buffer (but the actual socket has data concatenated so this did not help)
It's normal for it to work this way. It's up to you to define your own protocol for splitting up data, for example you might to choose to start each transmission with 4 bytes telling you how long that transmission is.
Simples - TCP cannot transfer any messages longer than one byte - it's an octet/byte stream.
If you want to transfer messages longer than one byte, you need another protocol on top of TCP.
I have a socket connection that receives data, and reads it for processing.
When data is not processed/pulled fast enough from the socket, there is a bottleneck at the TCP level, and the data received is delayed (I can tell by the tmestamps after parsing).
How can I see how much TCP bytes are awaiting to be read by the socket ? (via some external tool like WireShark or else)
private void InitiateRecv(IoContext rxContext)
{
rxContext._ipcSocket.BeginReceive(rxContext._ipcBuffer.Buffer, rxContext._ipcBuffer.WrIndex,
rxContext._ipcBuffer.Remaining(), 0, CompleteRecv, rxContext);
}
private void CompleteRecv(IAsyncResult ar)
{
IoContext rxContext = ar.AsyncState as IoContext;
if (rxContext != null)
{
int rxBytes = rxContext._ipcSocket.EndReceive(ar);
if (rxBytes > 0)
{
EventHandler<VfxIpcEventArgs> dispatch = EventDispatch;
dispatch (this, new VfxIpcEventArgs(rxContext._ipcBuffer));
InitiateRecv(rxContext);
}
}
}
The fact is that I guess the "dispatch" is somehow blocking the reception until it is done, ending up in latency (i.e, data that is processed bu the dispatch is delayed, hence my (false?) conclusion that there was data accumulated on the socket level or before.
How can I see how much TCP bytes are awaiting to be read by the socket
By specifying a protocol that indicates how many bytes it's about to send. Using sockets you operate a few layers above the byte level, and you can't see how many send() calls end up as receive() calls on your end because of buffering and delays.
If you specify the number of bytes on beforehand, and send a string like "13|Hello, World!", then there's no problem when the message arrives in two parts, say "13|Hello" and ", World!", because you know you'll have to read 13 bytes.
You'll have to keep some sort of state and a buffer in between different receive() calls.
When it comes to external tools like Wireshark, they cannot know how many bytes are left in the socket. They only know which packets have passed by the network interface.
The only way to check it with Wireshark is to actually know the last bytes you read from the socket, locate them in Wireshark, and count from there.
However, the best way to get this information is to check the Available property on the socket object in your .NET application.
You can use socket.Available if you are using normal Socket class. Otherwise you have to define a header byte which gives number of bytes to be sent from other end.
I'm currently working on a server/client and the basics are almost done. But I'm having a problem with sending data after closing and opening the test client program.
This is how my disconnect method looks like:
public void Disconnect()
{
if (m_clientSocket != null)
{
m_clientSocket.Shutdown(SocketShutdown.Receive);
}
}
And the test data looks like this:
Client cl = new Client(888, "127.0.0.1");
cl.Connect(null);
cl.DataArrived += MyListenerMethod;
cl.Disconnect();
cl.Connect("hello");
cl.SendData("hello2");
Now the problem is it will send "hello" and "hello2" sometimes and sometimes just "hello" when I close and start the client program repeatedly.
I'm pretty sure that this is working according to design but I want all data sent before the program terminates, I'm guessing that I have to use delays or something along those lines to achieve this. I know this may seem like a trivial question but I'm wondering if this is possible or not.
Sounds like the socket is buffering the data to be sent, but isn't flushing the socket when its shut down. The result is that if you attempt to shut down the socket too soon the buffered data is never sent.
According to this blog article you may have more luck with the NetworkStream class.
Flush Socket in .NET or C#
(Alternatively use WCF or .Net remoting and have it deal with all this messy stuff)
My application in c# wants to cominicate with 3rd party Tcp server to send data and recieve back response messages ...The syntax of commands has UShort,ULONG,BYTE type datas
a sample command that needed to send by my app is
USHORT 0xFFFF
USHORT 0x00D0
BYTE 0xDD
then in app i send data as
TcpClient tcpClient = new TcpClient();
tcpClient.Connect("XX.XX.XX.XX",portnumber);
Networkstream ns=tcpClient.GetStream();
StreamWriter sw=new StreamWriter(ns);
sw.Write(0xFFFF);
sw.Write(0x00DD);
sw.Write(0x00);
//or send them bytes
sw.Write(0xFF);
sw.Write(0xFF);
sw.Write(0x00);
sw.Write(0xD0);
sw.Write(0x00);
sw.Write(0x00);
and I read incoming messages over server as
while (true)
{
byte[] buff=new byte[tcpClient.ReceiveBufferSize];
ns.Read(buff, 0, tcpClient.ReceiveBufferSize);
string dv= BitConverter.ToString(buff));
}
//returned data looks like FF-A2-00-23-00-02-00-00-00-00-00-00-D9-2E-20-2E-00-A0-04-00-AE-08
//yes i know this byte syntaxes but returning data is not that i look response for command that i sent..
but returning values are not that i look for
Is there any wrong on my code with sending data to server??
and any recomendations on reading writing datas are welcome...
Nobody can tell you what's wrong with the response when they don't know the protocol employed. The server's sending that because it feels like it... it might be something wrong with your request, or it might be a message indicating that it's offline for service. You can only check it's specification on how to interpret the result it did send, or ask the people who maintain it.
Might also be a good idea to tag this question with the language you're using, so people can make sense of the function calls and whether you're invoking them properly.
I'd also recommend using a packet sniffer (or on Linux simply strace) to show the packets being read and written... you will probably see the mistakes there. Then, use another program to interact with the server that does work, and compare bytes.
I'm sending a large amount of data in one go between a client and server written C#. It works fine when I run the client and server on my local machine but when I put the server on a remote computer on the internet it seems to drop data.
I send 20000 strings using the socket.Send() method and receive them using a loop which does socket.Receive(). Each string is delimited by unique characters which I use to count the number received (this is the protocol if you like). The protocol is proven, in that even with fragmented messages each string is correctly counted. On my local machine I get all 20000, over the internet I get anything between 17000-20000. It seems to be worse the slower connection that the remote computer has. To add to the confusion, turning on Wireshark seems to reduce the number of dropped messages.
First of all, what is causing this? Is it a TCP/IP issue or something wrong with my code?
Secondly, how can I get round this? Receiving all of the 20000 strings is vital.
Socket receiving code:
private static readonly Encoding encoding = new ASCIIEncoding();
///...
while (socket.Connected)
{
byte[] recvBuffer = new byte[1024];
int bytesRead = 0;
try
{
bytesRead = socket.Receive(recvBuffer);
}
catch (SocketException e)
{
if (! socket.Connected)
{
return;
}
}
string input = encoding.GetString(recvBuffer, 0, bytesRead);
CountStringsIn(input);
}
Socket sending code:
private static readonly Encoding encoding = new ASCIIEncoding();
//...
socket.Send(encoding.GetBytes(string));
If you're dropping packets, you'll see a delay in transmission since it has to re-transmit the dropped packets. This could be very significant although there's a TCP option called selective acknowledgement which, if supported by both sides, it will trigger a resend of only those packets which were dropped and not every packet since the dropped one. There's no way to control that in your code. By default, you can always assume that every packet is delivered in order for TCP and if there's some reason that it can't deliver every packet in order, the connection will drop, either by a timeout or by one end of the connetion sending a RST packet.
What you're seeing is most likely the result of Nagle's algorithm. What it does is instead of sending each bit of data as you post it, it sends one byte and then waits for an ack from the other side. While it's waiting, it aggregates all the other data that you want to send and combines it into one big packet and then sends it. Since the max size for TCP is 65k, it can combine quite a bit of data into one packet, although it's extremely unlikely that this will occur, particularly since winsock's default buffer size is about 10k or so (I forget the exact amount). Additionally, if the max window size of the receiver is less than 65k, it will only send as much as the last advertised window size of the receiver. The window size also affects Nagle's algorithm as well in terms of how much data it can aggregate prior to sending because it can't send more than the window size.
The reason you see this is because on the internet, unlike your network, that first ack takes more time to return so Naggle's algorithm aggregates more of your data into a single packet. Locally, the return is effectively instantaneous so it's able to send your data as quickly as you can post it to the socket. You can disable Naggle's algorithm on the client side by using SetSockOpt (winsock) or Socket.SetSocketOption (.Net) but I highly recommend that you DO NOT disable Naggling on the socket unless you are 100% sure you know what you're doing. It's there for a very good reason.
Well there's one thing wrong with your code to start with, if you're counting the number of calls to Receive which complete: you appear to be assuming that you'll see as many Receive calls finish as you made Send calls.
TCP is a stream-based protocol - you shouldn't be worrying about individual packets or reads; you should be concerned with reading the data, expecting that sometimes you won't get a whole message in one packet and sometimes you may get more than one message in a single read. (One read may not correspond to one packet, too.)
You should either prefix each method with its length before sending, or have a delimited between messages.
It's definitely not TCP's fault. TCP guarantees in-order, exactly-once delivery.
Which strings are "missing"? I'd wager it's the last ones; try flushing from the sending end.
Moreover, your "protocol" here (I'm taking about the application-layer protocol you're inventing) is lacking: you should consider sending the # of objects and/or their length so the receiver knows when he's actually done receiving them.
How long are each of the strings? If they aren't exactly 1024 bytes, they'll be merged by the remote TCP/IP stack into one big stream, which you read big blocks of in your Receive call.
For example, using three Send calls to send "A", "B", and "C" will most likely come to your remote client as "ABC" (as either the remote stack or your own stack will buffer the bytes until they are read). If you need each string to come without it being merged with other strings, look into adding in a "protocol" with an identifier to show the start and end of each string, or alternatively configure the socket to avoid buffering and combining packets.