actionscript Socket and XMLSocket read full data - sockets

as I can see in XMLSocket the data can be readed fully until the end, on the other hand the Socket class read data by parts, so long string will be concatinated by parts, I wonder if is possible to use the Socket class and still read the full data until the end package
private function readResponse():void {
var str:String = readUTFBytes(bytesAvailable);
response += str;
trace2(response);
}
private function socketDataHandler(event:ProgressEvent):void {
trace2("socketDataHandler: " + event);
readResponse();
}
so as I've saw in the docs the only data handler is the ProgressEvent, but how to handle the data to get the full string, not by parts?, I don't want to use the XMLSocket, is there a way?

XMLSocket reads data in internal buffer, and when terminating null byte is received it parses all of the XML received since the previous zero byte or, if that is the first message received, since the connection was established.
You need to wrap Socket object, read messages to internal buffer and fire event when you need.

Related

In UWP StreamSocket, can I read data with timeout and leave the connection open if timeout elapses

As I couldn't find any way to peek for data (read data without consuming the buffer) as asked at How to peek StreamSocket for data in UWP apps I'm now trying to make my own "peek" but still no luck.
I don't see how I can read data from StreamSocket in the manner which will let me use timeouts and leave the connection usable in case if timeout elapses.
In the end, the problem is as follows. In my, let's say, IMAP client, I get response from a server and if this response is negative, I need to wait a bit to see if the server immediately sends yet another response (sometimes, the server can do it, with extra details on the error or even a zero packet to close the connection). if the server didn't send another response, I'm fine, just leaving the method and returning to the caller. The caller can then send more data to the stream, receive more responses, etc.
So, after sending a request and getting initial response I need in some cases to read socket once again with a very small timeout interval and if no data arrives, just do nothing.
You can use a CancelationTokenSource to generate a timeout and stop an async operation.
The DataReader consumes the data from the input stream of the StreamSocket. Its LoadAsync() method will return when there is at least one byte of data. Here, we are adding a cancellation source that will cancel the asynchronous task after 1 second to stop the DataReader.LoadAsync() if no data has been consumed.
var stream = new StreamSocket();
var inputStream = stream.InputStream;
var reader = new DataReader(inputStream);
reader.InputStreamOptions = InputStreamOptions.Partial;
while(true)
{
try
{
var timeoutSource = new CancellationTokenSource(TimeSpan.FromSeconds(1));
var data = await reader.LoadAsync(1).AsTask(timeoutSource.Token);
while(reader.UnconsumedBufferLength > 0)
{
var read = reader.ReadUInt32();
}
}
catch(TaskCanceledException)
{
// timeout
}
}
Do no forget that disposing the DataReader will close the stream and the connection.

Receiving data from lua tcp socket without data size

I've been working in a socket tcp connection to a game server. The big problem here is that the game server send the data without any separators - since it sends the packet lenght inside the data -, making impossible to use socket:receive("*a") or "*l". The data received from the server does not have a static size and are sent in HEX format. I'm using this solution:
while true do
local rect, r, st = socket.select({_S.sockets.main, _S.sockets.bulle}, nil, 0.2)
for i, con in ipairs(rect) do
resp, err, part = con:receive(1)
if resp ~= nil then
dataRecv = dataRecv..resp
end
end
end
As you can see, I can only get all the data from the socket by reading one byte and appending it to a string, not a good way since I have two sockets to read. Is there a better way to receive data from this socket?
I don't think there is any other option; usually in a situation like this the client reads a packet of specific length to figure out how much it needs to read from the rest of the stream. Some protocols combine new line and the length; for example HTTP uses line separators for headers, with one of the headers specifying the length of the content that follows the headers.
Still, you don't need to read the stream one-by-one character as you can switch to non-blocking read and request any number of characters. If there is not enough to read, you'll get partially read content plus "timeout" signaled, which you can handle in your logic; from the documentation:
In case of error, the method returns nil followed by an error message
which can be the string 'closed' in case the connection was closed
before the transmission was completed or the string 'timeout' in case
there was a timeout during the operation. Also, after the error
message, the function returns the partial result of the transmission.

How to calculate the offset value for Jetty 8 web socket sendMessageMethod

I have a project where a proxy sends Base64 encoded messages to the server. The server then decodes the messages into a byte array and sends to the client. The Jetty 8 WeboScoket.Connection sendMessage(data, offset, length) method expects an offset.
Question how does one determine this offset when decoding from base64?
Also is it okay to assume that the length parameter is the converted byte array's length?
def onMessage(message:String) {
println("From client: " + message)
val decoded = Base64.decodeBase64(message)
println("Decoded and sent to the client: " + decoded)
serverSocket.connection.sendMessage(decoded, offset???, decoded.length)
}
tl;dr: It's an offset into decoded, supporting the case that only a part of an array is to be sent. Here, this parameter probably should be 0.
The link you've put into your message points to API v7, not 8.
Grep coding for org.eclipse.jetty.websocket.connection, I've followed this one in jetty-websocket. Then you can find types implementing that method -- e.g. WebSocketConnectionD00. You see your data mysteriously disappearing into the addFrame method of another interface, WebSocketGenerator. Now here's finally the real meat.
This is pretty low-level here, you can find the data being put into yet another abstraction:
private Buffer _buffer;
...
_buffer.put(content, offset + (payload - remaining), chunk);
One more down, and here's the info. Wait... no. Either grepcode is showing wrong data here or the devs copy/pasted the comments from the void put(byte b) to the two methods below, just adapting the comment on the returned value.
One more down, and you finally see what's happening:
System.arraycopy(b, offset, dst_array, index, length);
, where b is the decoded byte[]. Unfortunately, using grepcode, one cannot dive into that implementation.
Note that I don't use Jetty. Just wanted to look into some other code...

Unity3d c# TCP client code can't receive second message in a row

I have similar problem maybe the same like here.
From the server (Java TCP Server) im doing this:
public void sendMsg(String msg) {
out.println(msg); // msg is: "MSG Hello" without quetes
out.flush();
}
when i push it twice or more i receive only first message in client code which is unity3d code c# socket
void Update() {
if(connected) {
try {
if(theStream.DataAvailable) {
String data = sr.ReadLine();
// bla bla
Get rid of the if(theStream.DataAvailable). You cannot check if data is available that way since if you have already received it, it is not available. While the ReadLine function only returns one line to you, it may read much more than one line.
So here's what happens:
All data is sent.
Data is available, you call ReadLine. It reads all the data and returns one line to you.
No data is available now, since it has already been read from the connection.
There are other problems with that check too. If it's trying to avoid calling ReadLine if a line isn't available, it won't do that. Some data being available doesn't mean a whole line is. (Imagine if the other end maliciously sends just a single X byte.)

How to read the whole message with Chilkat socket?

I need to get the whole message(response), but socket.ReceiveBytes(); returns just part of the message. I tried to loop it but it fails on timeout when no bytes to receive.
List<byte> lb = new List<byte>();
byte[] receivedMsg = socket.ReceiveBytes();
while (receivedMsg.Length > 0)
{
lb.AddRange(receivedMsg);
receivedMsg = socket.ReceiveBytes();
}
So, how I can check if there are byte to read? How I can read the whole message?
Since its a Chilkat implementation, you should probably contact the developer. But I found this that could help: http://www.cknotes.com/?p=302
Ultimately, you need to know how much to read from the socket to constitute a whole message. For example, if the overlying protocol is a portmapper, then you know that you are expecting messsages in the format that the RFC specifies (http://tools.ietf.org/html/rfc1833.)
If you are rolling your own protocol over a socket connection, then use the method in the Chilkat blog post about putting the size of the total message in the first 4 bytes.