- Home /
Android Tcp Socket Problem
hi everyone,
finished a server / client project to send and receive packets. The project works fine on the computer, but android only sends 3-4 large packages and never sends after them.No problem with small packets on android. There is no problem getting the server out of the box, but the android is having trouble sending large packets.I can give you skype if you can help. I share my code down there and I'm waiting for help. Thx...
client:
void SendWhole(Socket sock, IPacket packet)
{
var stream = new MemoryStream();
var writer = new BinaryWriter(stream);
byte[] payload = packet.ToBytes();
writer.Write((short)packet.GetOpcode());
writer.Write(payload.Length);
writer.Write(payload);
byte[] bufferCopy = new byte[stream.ToArray().Length];
System.Buffer.BlockCopy(stream.ToArray(), 0, bufferCopy, 0, bufferCopy.Length);
sock.Send(bufferCopy,0,bufferCopy.Length ,SocketFlags.None );
}`
my server recieve method:
private void ProcessReceive(SocketAsyncEventArgs e)
{
var state = (StateObject)e.UserToken;
// Check if the remote host closed the connection
if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
{
// Opcode not set -> Header has not been parsed yet
if (state.Opcode == -1)
{
ReadHeader(e);
}
else
{
ReadBody(e);
}
}
else
{
CloseClientSocket(e);
}
}
private void ReadHeader(SocketAsyncEventArgs e)
{
var state = (StateObject)e.UserToken;
state.TotalBytesRead += e.BytesTransferred;
// If header isn't read fully, read more
if (state.TotalBytesRead < HeaderLength)
{
int missing = HeaderLength - state.TotalBytesRead;
e.SetBuffer(e.Buffer, e.Offset, missing);
}
else
{
// Received full header, parse it and read packet body
state.Opcode = BitConverter.ToInt16(state.Buffer, 0);
state.PacketDataLength = BitConverter.ToInt32(state.Buffer, 2);
state.PacketData = new byte[state.PacketDataLength]; // TODO: Hot-Spot, use pooled buffers to avoid GC overhead
state.TotalBytesRead = 0;
e.SetBuffer(state.PacketData, 0, state.PacketDataLength);
}
BeginReceive(e);
}
private void ReadBody(SocketAsyncEventArgs e)
{
var state = (StateObject)e.UserToken;
Console.WriteLine("GETTED LEGenTH = " + state.PacketData.Length.ToString());
// Body not received fully, read more
if (e.BytesTransferred < state.PacketDataLength)
{
var missing = state.PacketDataLength - e.BytesTransferred;
e.SetBuffer(state.PacketData, e.Offset, missing);
Console.WriteLine("GET DATA CORPUT!");
//////////////////////////////////////////////////// I GET HERE ON ANDRIOD!////////////////////////////////////
}
else
{
// Publish packet to business logic (DON'T BLOCK THERE, use worker threads if needed)
OnPacketReceived(state.Opcode, state.PacketData);
// Don't forget to reset this
e.SetBuffer(state.Buffer, 0, HeaderLength);
state.TotalBytesRead = 0;
state.Opcode = -1;
}
BeginReceive(e);
var packet = CreateRandomPacket();
if (state.ClientSocket.Connected)
SendWhole(state.ClientSocket, packet);
}
Answer by Bunny83 · Jul 15, 2017 at 03:50 PM
Your question sounds a bit confusing. The provided code snippet makes it hard to follow what happens, especially your receiving code.
Are you aware of the fact that TCP is a stream protocol and not a packet protocol. Of course the stream is transmitted with one or multiple packets but from the application point of view a TCP connection just provides a data stream. A stream can be splitted (fragmented) across multiple packets however TCP ensures that the data arrives in the right order. The MTU size can vary between different hardware implementations as well as different operating systems. If the data you send + protocol overhead is larger than the MTU size the data need to be splitted.
Receiving code for a TCP connection should always use a buffer where it can append the next data chunk once it arrived. If you plan to send "packets" over a TCP connection you have to manually detect the beginning and end of your packet as TCP is an endless stream of bytes which can arrive at any speed / fragmentation.
Not related to $$anonymous$$TU size.
i have this: I do not see a problem when I put a ThreadSleep(50) on the ProcessReceive function. But I do not have to set a ThreadSleep for my fast data transfer. what should I do?
Sorry, but the amount of information that you provided is simply not enough to follow what happens. If you use BeginReceive it might be a concurency problem. $$anonymous$$eep in $$anonymous$$d that a byte buffer must only be accessed by a single thread at a time. If you run your business logic on a seperate thread, make sure you only work on a copy of the data.
But again, we don't know how you actually receive the data and how you further process it. We don't even know what "SetBuffer" actually does. How exactly do you stitch a fragmented packet back together?
my full project: https://yadi.sk/d/nBxIgWh$$anonymous$$3L8hW8
i want send continuousy big data.
I need to talk to you live. Can you add me on skype(username:ozln61) or another one?