Android and C# tcp connection sockets - java

my question isn't about creating the connection. My question is about reading the stream in the c# code. The java android code is sending 3 parameters by DataOutputStream. the C# code get them all, but in different sockets. I mean if I have the array byte received it will be in 2 diffrent messagess. Let's see the code and it be clearly.
Java code :
private DataOutputStream out;
InetAddress serverAddr = InetAddress.getByName("192.168.43.145");
socket = new Socket(serverAddr, port);
out = new DataOutputStream(socket.getOutputStream());
// Header
out.writeByte(IDMessage); // example :IDMessageis is 1
// Data
out.writeDouble(LongX); // example :LongX is 35.4
out.writeDouble(LatY); // example :LatY is 31.5
out.flush();
and c# code reading :
// Data is the array byte received (byte[])
using (memory = new MemoryStream(data))
{
using (r = new BinaryReader(memory))
{
IDMessage = r.ReadInt32();
Long = r.ReadDouble();
Lat = r.ReadDouble();
}
}
Again: The problem is that the massage is received in 2 different byte array. I mean 1 array will be 1,0,0,0,..... and the other array in different massage will be 35.4,31.5,0,0,0,0,......
Any one have any idea why it happen? Thanks. :)
Edit : by the way it the message two, in the first massage I just need to send one parameter so it work's great by the sending and reading, in the two massage it send the 1 parameter alone and in other socket the two doubles.
Edit : The proxy code :
int k=0;
byte[] byteRecived = new byte[1024];
// Start Listeneting at the specified port
listenerForAndroid.Start();
// Now the server is running and waiting for a client connection.
sender = listenerForAndroid.AcceptSocket(); // Client Accepted
while (IsListener)
{
try
{
k = sender.Receive(byteRecived); // The server is resieved message . This line is get 2 other massages.
Header h = new Header(byteRecived);
message = MessageFactory.getMessage(h);
if (message is RequestID)
{
counterObserver ++;
SendIDMessage(sender,counterObserver);
}
message.DeSerialize(byteRecived);
message.Execute();
}
catch
{
}

Related

C# Sockets programming, received sockets length isn't correct

I'm doing a chat application between C# clients and a java server.
I need to send a lot of sockets from the server to the client when he connects. I want to send the logs of the day. So I have all logs in a file.txt, and I send them to the new connected client.
For sending them, I have a for loop until all the logs are sent. Here is the loop:
for (String item : Logs) {
client.send("log:" + item);
}
And for the send method:
public void send(String text) {
//'os' is the: Socket.getOutputStream();
//What the server will send to the client
PrintWriter Out = new PrintWriter(os);
// 0 is the offset, not needed
Out.write(text, 0, text.length());
Out.flush();
System.out.println(text.length());
}
So until there, all works well.
Now my problem is: The output stream sends bytes length like '30', '100', '399' who is 'text.length()', and the C# client receive all sockets, but paste 2 or 3 sockets in one.
E.g: if I send with separated sockets (each line is a out.write() and out.flush() because I call the send method for each line)
(Server-side)
log:abcdefghijklmnopqrstuvwxyz123456789101112131415
log:abcdefghijklmnopqrstuvwxyz
log:abcdefghijklmnopqrstuvwxyz123456789101
log:abcdefghijklmnopqrstuvwxyz1234567891011121314151617
log:abcdefghijklmnopqrst
log:abcdefghijklmnopqrstuvwxyzyxwvu
The sockets will be at the end:
(Client-side)
log:abcdefghijklmnopqrstuvwxyz123456789101112131415log:abcdefghijklmnopqrstuvwxyzlog:abcdefghijklmnopqrstuvwxyz123456789101
log:abcdefghijklmnopqrstuvwxyz1234567891011121314151617log:abcdefghijklmnopqrst
log:abcdefghijklmnopqrstuvwxyzyxwvu
And if I check the sockets length in the server side I get like;
20
12
15
17
20
But in the client side;
32
15
37
The sum of multiples sockets put together.. (And sometimes it's 3 sockets put together, and sometimes 2, sometime 4...) I cant understand why...
Here's my Async method for receiving the sockets from the server;
private void callBack(IAsyncResult aResult)
{
String message = "";
try
{
int size = sck.EndReceiveFrom(aResult, ref ip);
if (size > 0)
{
byte[] receive = new byte[size];
receive = (byte[])aResult.AsyncState;
message = Encoding.Default.GetString(receive, 0, size);
Debug.WriteLine(message.Length);
}
byte[] buffer = new byte[1024];
//restart the async task
sck.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref ip, new AsyncCallback(callBack), buffer);
}
catch (Exception) { }
}
Where the int 'size' contains the size of the byte[] received, and here is the problem. How can I get the right sockets I sent from the server?
If I send each socket with delay in the server side (like 15ms), the client can get the sockets one by one. But only if you have a good connection. If your connection do like 200ms of latency, you will get the sockets grouped... So the problem is in the client side (I think...). The server (java) side works correctly, the flush method always send the socket!
UPDATE:
Here are my sockets;
//Global var
EndPoint ip;
public Socket sck;
//How I connect my sockets
private void connect()
{
ip = new IPEndPoint(IPAddress.Parse("127.0.0.1"), mysql.selectPort());
sck = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
sck.Connect(ip);
}catch(Exception e) {
Debug.WriteLine(e.Message);
}
}

Unable to correct StreamCorruptedException in full duplex code [duplicate]

This question already has an answer here:
StreamCorruptedException: invalid type code: AC
(1 answer)
Closed 6 years ago.
I am trying to implement a full duplex TCP connection between two applications.
My gist of the idea is to do the following :
Client
socket.connect(ServerAddress,Timeout);
socketArray.add(socket);
outputStream = new ObjectOutputStream(socket.getOutputStream());
outputStream.writeObject(message);
outputStream.flush();
/** Wait for reply**/
inputStream = new ObjectInputStream(socket.getInputStream());
message = (Message)inputStream.readObject();
if (message.type == X) {
replyToServer(message,socketArray);
}
replyToServer(Message,socketArray) {
for(Socket socket : socketArray) {
outputStream = new ObjectOutputStream(socket.getOutputStream()); // **getting streamCorruptedException** here
outputStream.writeObject(message);
outputStream.flush();
}
}
Server
Here I listen to the incoming connections, and dependent on the message type, I want to reply to it after changing some parameters of the message.
inputStream = new ObjectInputStream(clientSocket.getInputStream()); //notice inputStream and outputStream are created only once here, maybe that is the issue ?
outputStream = new ObjectOutputStream(clientSocket.getOutputStream());
while ( (message = (Message)inputStream.readObject() ) != null) {
if (message.type == Y) {
message.type = X ; //notice this is used in Client code
outputStream.writeObject(message);
outputStream.flush();
} else if (message.type == X ) {
// don't send anything to client, we are done processing this message
}
}
After looking around in google, I got some idea that ObjectInputStream and ObjectOutputStream must be somehow synchronized. But I did not get a concrete understanding. If someone can point out mistake in my code, it will be helpful.
Code flow :
Client sends a message to server with message type Y, asking for information.
Server sees the type Y, sets information in the object, changes message type to X, and replies to client.
Client receives replies from all others.
Note : There are 5 applications running both server and client. Hence the client will wait until it gets replies from all the others before proceeding.
Now client must send the received information to all 5 applications, and does that in replyToServer method. The exception occurs there.
PS : This is pseudo code, and if any more details are required to understand code flow , please let me know in the comments.
Actual stack trace
err: java.io.StreamCorruptedException
err: at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1530)
err: at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1483)
.....`
outputStream = new ObjectOutputStream(socket.getOutputStream()); // **getting streamCorruptedException** here
Impossible. You are getting StreamCorruptedException: invalid type code AC at the other end when you execute new ObjectInputStream(...).
The reason is that you've created multiple ObjectOutputStreams for the same socket, but without creating correspondingly multiple ObjectInputStreams at the peer. You should use the same object input and output streams for the life of the socket, at both ends.
while ( (message = (Message)inputStream.readObject() ) != null) {
This isn't valid either. ObjectInputStream.readObject() doesn't return null at end of stream. It can return null any time you wrote a null. The loop should terminate when EOFException is thrown.

Java socket unable to send two byte arrays

I am trying to send two byte arrays over a Java socket. I have captured the data via wireshark and it shows that the first byte array sends; the second, however, doesn't send at all.
I am using Linux Mint and Oracle's JRE (not OpenJDK).
byte[] packet_one = new byte[] {(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x50};
byte[] packet_two = new byte[] {(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x78};
Socket sck;
DataInputStream dis;
DataOutputStream dos;
try {
sck = new Socket(IP_ADDRESS,PORT);
dis = new DataInputStream(sck.getInputStream());
dos = new DataOutputStream(sck.getOutputStream());
int recv_header = dis.ReadInt(); // This receives the correct response.
dos.write(packet_one); // Sends fine.
dos.write(packet_two); //Does not send.
int data_length = dis.readInt(); // No more data received.
}catch(Exception e) {
System.out.println("Error: " + e.getMessage());
}
So, dos.write(packet_one) works (confirmed by wireshark). Writing packet_two doesn't work. The data_length returns 0 since I don't receive anymore data either. No errors or exceptions get caught.
I have also tried using dos.flush(), but it doesn't make a difference.
Any ideas on why this may be the case?
Maybe you're exiting the program before there's time to send the buffered bytes?
Perhaps if you add something like:
for (;;) {
final byte x = dis.readByte();
System.out.println("got byte: " + (x & 0xFF));
}
the program won't exit, and you'll also see if there are more bytes that the server sent back. Might offer clues.
And, in case you don't know, readInt() reads for bytes and returns an int made from those bytes, which is 0 if all the for bytes read are zero. So your comment 'No more data received.' feels a bit ambiguous.
You could also try inserting a
sck.setTcpNoDelay(true);
after creating the socket. Writes should then go on the network immediately. I think.
Hope this helps.

Read and Write Bytes data packet via socket

I want to connect Android Device to external device via Socket. Socket Connect to external device successfully.
Now if any data require from external device then send request of byte packet data to socket below order. if external device receive data correct then send byte data in response.
Parameters : methodname(1 byte), payloadlength(2 byte), payload(2 byte).
Now My Code is...
Socket socket = new Socket("local exteranl device ip", 5000);
if(socket.isConnected()) {
int methodname = 5;
int payload = 2151;
int payloadLength = 2;
ByteBuffer buffer = ByteBuffer.allocate(3 + payloadLength); // 3 = for method name + length
buffer.order(ByteOrder.BIG_ENDIAN); // Just to be explicit
buffer.put((byte) methodname);
buffer.putShort((short) payloadLength);
buffer.putShort((short) payload);
buffer.rewind();
byte[] result = new byte[buffer.capacity()]; // Could also use result = buffer.array();
buffer.get(result);
DataOutputStream classOUTstream = new DataOutputStream(socket.getOutputStream());
// socket is already connected
classOUTstream.write(result);
classOUTstream.flush();
InputStream stream = socket.getInputStream();
byte[] data = new byte[100];
int count = stream.read(data);
}
Above Code is Android, i knowing only basic concept of java. i am getting -1 result in count.
can any one please suggest me or tell me my mistake?
You're doing this the hard way. Get rid of the ByteBuffer altogether and use all the methods of DataOutputStream. They are all big-endian. I can't see any mistake but clearly you must be sending something the peer didn't understand so he is closing the connection instead of sending a reply.
Note: Socket.isConnected() cannot possibly be false at the point you're testing it.

Send and receive serialize object on UDP

I am trying to send a serialized object from a server process to a client process in Java using UDP. The problem is that the client is being blocked on the receive method. Can someone help?!
here is the server code for sending the object:
ClientModel C1= new ClientModel(100,"Noor","Noor",38,38,"asd");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(C1);
oos.flush();
byte[] Buf= baos.toByteArray();
packet = new DatagramPacket(Buf, Buf.length, client, port);
socket.send(packet);
and here is the client code for receiving the object:
byte[] buffer = new byte[100000];
packet = new DatagramPacket(buffer, buffer.length );
socket.receive(packet);
System.out.println("packet received");
I just want to receive the object to be able to reconstruct but I cannot receive the packet itself.
I dont know what you want to accomplish in the end, but working with UDP is not so easy... the main reason is in the Description of the DatagramPacket Object:
Datagram packets are used to implement
a connectionless packet delivery
service. Each message is routed from
one machine to another based solely
on information contained within that
packet. Multiple packets sent from
one machine to another might be routed
differently, and might arrive in any
order. Packet delivery is not
guaranteed.
A good tutorial when working with udp is http://download.oracle.com/javase/tutorial/networking/datagrams/clientServer.html
About your blocking:
Receives a datagram packet from this
socket. When this method returns, the
DatagramPacket's buffer is filled with
the data received. The datagram packet
also contains the sender's IP address,
and the port number on the sender's
machine.
This method blocks until a datagram is
received. The length field of the
datagram packet object contains the
length of the received message. If the
message is longer than the packet's
length, the message is truncated.
I didnt really test it, but I am pretty sure - based on the description - that the datagramsocket.reseive function will block until the packet is filled (in your case until 100000 bytes are received).
I would suggest you start with a datagrampacket with a fixed known length, where you transmit the size of the actual payload. Something like:
public static void main(String[] args) {
ClientModel c1 = new ClientModel ();
c1.data = 123;
c1.name = "test";
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(c1);
oos.flush();
// get the byte array of the object
byte[] Buf= baos.toByteArray();
int number = Buf.length;;
byte[] data = new byte[4];
// int -> byte[]
for (int i = 0; i < 4; ++i) {
int shift = i << 3; // i * 8
data[3-i] = (byte)((number & (0xff << shift)) >>> shift);
}
DatagramSocket socket = new DatagramSocket(1233);
InetAddress client = InetAddress.getByName("localhost");
DatagramPacket packet = new DatagramPacket(data, 4, client, 1234);
socket.send(packet);
// now send the payload
packet = new DatagramPacket(Buf, Buf.length, client, 1234);
socket.send(packet);
System.out.println("DONE SENDING");
} catch(Exception e) {
e.printStackTrace();
}
}
On the other side you now KNOW your sizes:
public static void main(String[] args) {
try {
DatagramSocket socket = new DatagramSocket(1234);
byte[] data = new byte[4];
DatagramPacket packet = new DatagramPacket(data, data.length );
socket.receive(packet);
int len = 0;
// byte[] -> int
for (int i = 0; i < 4; ++i) {
len |= (data[3-i] & 0xff) << (i << 3);
}
// now we know the length of the payload
byte[] buffer = new byte[len];
packet = new DatagramPacket(buffer, buffer.length );
socket.receive(packet);
ByteArrayInputStream baos = new ByteArrayInputStream(buffer);
ObjectInputStream oos = new ObjectInputStream(baos);
ClientModel c1 = (ClientModel)oos.readObject();
c1.print();
} catch(Exception e) {
e.printStackTrace();
}
}
The CientModel clas sI used:
public class ClientModel implements Serializable{
private static final long serialVersionUID = -4507489610617393544L;
String name = "";
int data = 1;
void print() {
System.out.println(data +": " + name);
}
}
I tested this code and it works just fine. Hope that helps (I got the byte-To-int and around from http://www.tutorials.de/java/228129-konvertierung-von-integer-byte-array.html)
Edit: As stated in the comments, it is often a very bad idea to use UDP, mainly, because you do not know if your packets are received in the correct order, or even at all. UDP does NOT guarantee that. I didn't do too much udp programming, but the only part you can rely on (if I understood correctly) is, that if you get a packet and it fits within the datagram (65,527 bytes - see https://en.wikipedia.org/wiki/User_Datagram_Protocol) it will contain the whole thing. So if you do not care about the order in which the message come and your object fits in the datagram, you should be fine.
Edit2: As for the code: do not use it as is. it is only an example, ind UDP you should only have one type of packet, and this with a known size. that way you do not need to send the "size". If you use the code as shown above, and one packet is dropped, the next packet will be the wrong size (i.e. the first packet is dropped, suddenly you are checking the first bytes of the payload to get the size).
I didnt really test it, but I am pretty sure - based on the
description - that the datagramsocket.reseive function will block
until the packet is filled (in your case until 100000 bytes are
received).
This is wrong. The receive function will block until a datagram is received, which can be smaller than the buffer size (and usually will be). The method packet.getLength() will tell you how big it was.

Categories