Send an image from java client to python server - java

I am trying to send an image in the form of a byte array from a client application to a server. The server code is written in python while the client is written in java. The image is being transferred correctly however the image saved on the server machine is corrupted.
The following is the code for the server.
import socket
import struct
HOST = "192.168.1.100"
PORT = 9999
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(5)
print('SERVER STARTED RUNNING')
while True:
client, address = s.accept()
buf = ''
while len(buf) < 4:
buf += client.recv(4 - len(buf))
size = struct.unpack('!i', buf)[0]
with open('/home/isaac/Desktop/image.jpg', 'wb') as f:
while size > 0:
data = client.recv(1024)
f.write(data)
size -= len(data)
print('Image Saved')
client.sendall('Image Received')
client.close()
The following is the source code for the java client:
public static void main(String[] args) throws IOException {
byte[] array = extractBytes("/home/isaac/Desktop/cat.jpg");
Socket sock = new Socket(IP_ADDRESS, PORT_NO);
DataOutputStream dos = new DataOutputStream(sock.getOutputStream());
System.out.println("Array Length - " + array.length);
dos.writeInt(array.length);
dos.write(array);
BufferedReader reader = new BufferedReader(new InputStreamReader(sock.getInputStream()));
System.out.println(reader.readLine());
}
Hopefully you can help me. I've tried to google to get my answer but no solution has worked so far.

In what sense you get a corrupted image? I've tried it with the following array:
byte[] array = new byte[3000];
for(int i=0; i<array.length; i++) {
array[i] = (byte)('0' + (i % 10));
}
and I get the same array I sent.
Another thing, just to be sure: the file is less than 2Gb, right?

This can help you
import java.nio.file.Files;
File file = new File("picture path");
byte[] array = Files.readAllBytes(file.toPath());

Related

Byte array message is splitted while sending. I want to send request message in single shot

Using java socket programming, sending byte array. Byte array size is 3500. It is not send as single request, splitted into 3 request while network capture. so server couldn't able to process the splitted request. I want to send the request in single shot. Find below the code snippet which am used for sending byte array request.
byte[] bISOMsg = new byte[9000];
bISOMsg = isoMsg.pack();
int messageLength = (short)bISOMsg.length;
messageLength = messageLength - 16;
/* System.out.println("messageLength --> " + messageLength);
System.out.println("Header --> " + new String(isoMsg.getHeader()));*/
byte[] bHeaderLen = new byte[2];
ByteBuffer bbHeader = ByteBuffer.wrap(bHeaderLen);
bbHeader.putShort((short)messageLength);
isoMsg.setHeader(bbHeader.array());
bISOMsg = isoMsg.pack();
isoMsg.unpack(bISOMsg);
logISOMsg(isoMsg);
System.out.println("bISOMsg....."+new String(bISOMsg));
byte[] BitmapBytVal= new byte[32];
System.arraycopy(bISOMsg, 4,BitmapBytVal, 0, 32);
//System.out.println("BitmapBytVal..."+BitmapBytVal);
ByteArrayOutputStream outputStream1 = new ByteArrayOutputStream();
outputStream1.write(isoHeader.getBytes());
outputStream1.write(bISOMsg, 0,4);
outputStream1.write( HexToByte1(new String(BitmapBytVal)));
outputStream1.write(bISOMsg, 36, bISOMsg.length-36);
TotalMsgBytVal =outputStream1.toByteArray();
outputStream1.close();
System.out.println("TotalMsgBytVal Hex value="+TotalMsgBytVal);
System.out.println("Msg Length ---- " + TotalMsgBytVal.length);
String msgLength= Integer.toHexString(TotalMsgBytVal.length);
msgLength = addZeros(msgLength,4);
System.out.println("Msg Length ----: " + msgLength);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream( );
String MSGIndicater="03NPCI ONC";
outputStream.write(MSGIndicater.getBytes());
outputStream.write(HexToByte1(msgLength));
outputStream.write(TotalMsgBytVal,0,TotalMsgBytVal.length);
outputStream.close();
TotalMsgBytVal = outputStream.toByteArray();
Socket soc = null;
byte []dataRes = new byte[9000];
System.out.println("Gateway IP Address ="+ cbsipaddr);
System.out.println("Gateway Port ="+ cbsport);
soc= new Socket(cbsipaddr,cbsport);
in=soc.getInputStream();
/*
/* Added by Syed on 03/09/15 */
System.out.println("Total Length of Request is = "+ TotalMsgBytVal.length);
DataOutputStream dout = new DataOutputStream(soc.getOutputStream());
dout.writeInt(TotalMsgBytVal.length); // write length of the message
dout.write(TotalMsgBytVal); // write the message
Thread.sleep(1000);
dout.flush();
Well, the MTU for an ethernet network is about 1500 bytes.
What do you think happens when you try to write 3500 bytes over ethernet?
Your code also looks very funky, I think you should look at an existing implementation to see how you can improve your code. If it can't handle messages that are split into multiple packets, it's a pretty bad server.

TCP: How to get response from Vb.net server in Android Client?

This is not a possible duplicate. No answer on this site adequately answers or solves my issue.
I am trying to connect to a VB.NET server via TCP socket and get response in Android application. The response is always null as string or -1 as bytes.
I have to connect and get a response for multiple platforms but for the moment I just want to focus on the Android app. Maybe if I figure it out, it will be easier to move forward to other platforms.
I do not have access to edit any code in the VB.NET live server. There system is pretty old and has been only sending responses to other Windows clients up until now.
Here is my Android client. It is inside a background task which is called from the mainActivity. The below command string should return coordinates in the form of a string from the server. Nothing is returned.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client {
public static void sendMessage() throws IOException, InterruptedException {
Socket socket = null;
String host = "";
int port = ;
PrintStream stream = null;
String command="";
try {
Socket s = new Socket(host,port);
System.out.println("Socket created");
//outgoing stream redirect to socket
OutputStream out = s.getOutputStream();
PrintWriter output = new PrintWriter(out);
output.println(command);
output.flush();
System.out.println("command sent");
BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream()));
//read line(s)
System.out.println("Getting response:");
String st = input.readLine();
System.out.println("Response : " + st);
//Close connection
s.close();
}
catch (UnknownHostException e) {
System.out.println("Don't know about host : " + host);
e.printStackTrace();
System.exit(1);
}
catch (IOException e) {
System.out.println("Couldn't get I/O for the connection to : " + host);
e.printStackTrace();
System.exit(1);
}
}
}
A developer also sent me a test client in VB which connects, sends and recieves without problem
Here is a class of a VB:NET Dummy server project the developer has sent me to see how the live server is setup code-wise. I can see it gets the string as unicode but I am not confident in VB to know where my Java code is going wrong.
When I open the project and start the server on localhost I cant connect to it from the java client anyway. Then I have written another client in PHP, same problem, connection established but no response. I downloaded a socket tester software but it also can connect but does not get a response.
Option Explicit On
Imports System
Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Imports Microsoft.VisualBasic
Imports System.Net.Dns
Imports System.Text.UnicodeEncoding
Imports System.Threading
Imports System.Data.SqlClient
Public Enum glenConnectionType
ConstantConnection = 1
ConnectOnDemand = 2
AsyncConnection = 3
End Enum
Public Class clsDynaListner
Public tcpServer As Socket
Public tcpClient As Socket
Public tcpPort As Integer
Public tcpBilnr As Integer ' was shared SHOULD PROB BE INITIALISED TO 0
Public ThreadClient As Thread
Public LastKontakt As Date = Nothing
Public ConActive As Boolean = False
Private tcpClientEndPoint As System.Net.IPEndPoint
Private bCommandLength(15), bReplyLength(15) As Byte
Private iCommandLength, iReplyLength As Integer
Private sReplyLength As String
Private sCommand, sReply As String
Private theCommandBytes() As Byte
Private theReplyBytes() As Byte
Private Const AsyncMaxBytes As Integer = 600000 '1024
Public Shared AsyncData As String = Nothing
Public Sub New(ByVal currentTCPPort As Integer, ByVal theConnectionType As glenConnectionType)
tcpPort = currentTCPPort
tcpClientEndPoint = New System.Net.IPEndPoint(System.Net.IPAddress.Any, tcpPort)
'Select Case theConnectionType
' Case glenConnectionType.ConstantConnection
' ThreadClient = New Threading.Thread(AddressOf ListenForConstantConnection)
' Case glenConnectionType.ConnectOnDemand
ThreadClient = New Threading.Thread(AddressOf ListenForConnectOnDemand)
' Case glenConnectionType.AsyncConnection
'ThreadClient = New Threading.Thread(AddressOf ListenForAsyncConnection)
'End Select
ThreadClient.Start()
End Sub
Private Sub ListenForConnectOnDemand()
While (True)
Try
tcpServer = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
tcpServer.SendBufferSize = TCP_BUFFER_SIZE
tcpServer.ReceiveBufferSize = TCP_BUFFER_SIZE
tcpServer.Blocking = True
tcpServer.Bind(tcpClientEndPoint)
tcpServer.Listen(0)
tcpClient = tcpServer.Accept
tcpClient.SendBufferSize = TCP_BUFFER_SIZE
tcpClient.ReceiveBufferSize = TCP_BUFFER_SIZE
' Find out how big the command is going to be
tcpClient.Receive(bCommandLength)
iCommandLength = CType(Unicode.GetString(bCommandLength), Integer)
' Bring that command to daddy
Array.Resize(theCommandBytes, iCommandLength + 1)
tcpClient.Receive(theCommandBytes)
sCommand = Unicode.GetString(theCommandBytes)
gInMessage = sCommand
' Get the reply
sReply = "Response:"
gOutMessage = sReply
' Inform the controller of the length of the reply transmission
iReplyLength = (sReply.Length * 2) - 1
sReplyLength = iReplyLength.ToString.PadLeft(8, "0")
bReplyLength = Unicode.GetBytes(sReplyLength)
tcpClient.Send(bReplyLength)
' Send the reply data
Array.Resize(theReplyBytes, iReplyLength + 1)
theReplyBytes = Unicode.GetBytes(sReply)
tcpClient.Send(theReplyBytes)
Array.Clear(theCommandBytes, 0, theCommandBytes.Length)
Array.Clear(theReplyBytes, 0, theReplyBytes.Length)
tcpClient.Close()
tcpServer.Close()
tcpClient = Nothing
tcpServer = Nothing
Catch ex1 As Exception
Try
tcpClient.Close()
tcpServer.Close()
tcpClient = Nothing
tcpServer = Nothing
' ErrMessage = "LisForContr :" & tcpPort.ToString & ex1.Message
Catch
End Try
End Try
End While
End Sub
Protected Overrides Sub Finalize()
Try
tcpServer.Close()
ThreadClient.Abort()
Catch
End Try
MyBase.Finalize()
End Sub
End Class
I have been working with this for a while. The apps I have built are complete for PHP Web App, Android Native, and iPhone Native. The problem is only getting the response from the VB server.
Would like some help to push me in the right direction.
Also I enquired with the developers if the response has a line-break. It does not and it does seem they are willing to mess with the code as it served there purpose for many many years. So I have to find away around that.
If you need me to provide more info just ask.
To send to a VB.NET server from Java you must send the string as unicoded bytes. Send the length at the bytes to expect first and then send the primary data and flush. You have to know exactly what the server is expecting in order to format and encode the data accordingly in preparation to send it.
I was able to successfully fix my issue after debugging VB client and server. This client will process byte arrays, stream advanced sql commands and get the response. The update will be getting xml table data. Anyone who wants to input how to make this client better. You are welcome.
Updated my java client as follows.
/**
* MR-TCP Java & VB.NET DataExchange Client 0.95 - Maze Runner 2015
*/
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
public class Client {
public static String sendCommand(String commandString, Boolean IsID) throws IOException, InterruptedException {
String host;
int port;
String command;
byte[] commandBytes;
String commandLength;
byte[] cmdLengthBytes;
Socket s;
DataOutputStream stream;
String dataString = "";
host = ""; //
port = 0; //
command = commandString;
commandBytes = command.getBytes("UTF-16LE"); // returns byte[18]
if(IsID){
commandLength = "00000021";
cmdLengthBytes = commandLength.getBytes("UTF-16LE");
} else {
String iCommandLength = command; // Get the command length
cmdLengthBytes = iCommandLength.getBytes("UTF-16LE");
int commandNewLength = cmdLengthBytes.length-1;
String newLength = "0000" + String.valueOf(commandNewLength);
cmdLengthBytes = newLength.getBytes("UTF-16LE");
}
try {
s = new Socket(host, port); // Connect to server
//Send the command to the server
stream = new DataOutputStream(s.getOutputStream()); // get ready to send
stream.write(cmdLengthBytes); // tell the server how many bytes to expect
System.out.println("Command length sent");
stream.write(commandBytes); // Send the command to papa...
stream.flush(); // guaranteed sending
System.out.println("Command sent");
//Receive the command from the server.
DataInputStream is = new DataInputStream(s.getInputStream()); // get ready to receive
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); // prepare to get array
int nRead;
byte[] data = new byte[1024];
while ((nRead = is.read(data, 0, data.length)) != -1) { // read the array byte by byte
buffer.write(data, 0, nRead);
}
byte[] dataBytes = buffer.toByteArray(); // get complete array
dataString = buffer.toString("UTF-16LE").substring(8); // get rid of the array length and convert to string
stream.close(); // close the dataStream
s.close(); // close the connection
System.out.println("Disconnected");
} catch (IOException e){
e.printStackTrace();
}
System.out.println("Function Complete");
System.out.println("Server response:" + dataString);
return dataString;
}
}

Java DatagramSocket throws a SocketTimeoutException after a few runs

I am writting a Java application that reads game server information. That's all it does, it runs in a loop doing the same thing.
The problem is that at first it works great, I get a response. After some(not a constant number) times it starts throwing the SocketTimeoutException.
This is the method I use for querying a SAMP server.
private ByteBuffer sendQuery(char opcode) throws IOException {
ByteBuffer bf = ByteBuffer.allocate(11);
bf.order(ByteOrder.LITTLE_ENDIAN);
bf.put("SAMP".getBytes("US-ASCII"));
bf.put(encodeIP(getIp()));
bf.putShort((short)getPort());
bf.put((byte)opcode);
Logger.getLogger().log("Request to " + this.getAddress().getHostString() + ":"+ByteConvert.bytesToHexString(bf.array()));
DatagramPacket packet = new DatagramPacket(bf.array(), bf.capacity(), getAddress().getAddress(), getPort());
getSocket().send(packet);
byte[] buffer = new byte[4096];
packet = new DatagramPacket(buffer, buffer.length, getAddress().getAddress(), getPort());
getSocket().receive(packet);
if(packet.getLength() > 4096)
Logger.getLogger().log("Large packet received from " + this.getIp() + " :"+packet.getLength());
bf = ByteBuffer.allocate(packet.getLength());
bf.order(ByteOrder.LITTLE_ENDIAN);
bf.put(buffer, 0, packet.getLength());
bf.flip();
return bf;
}
encodeIP method:
private static byte[] encodeIP(String s) throws IOException {
String[] ip = s.split("\\.");
byte[] bytes = new byte[ip.length];
for(int i = 0; i < ip.length; i++) {
bytes[i] = (byte)Integer.parseInt(ip[i]);
}
return bytes;
}
The protocol is documented here.
Other games have the same issue but currently i'm investigating SAMP as its protocol seems to be the simplest.
The application is running on Linux, Debian 7.0. I tried disabling the firewall completely.
So the reply got lost, or didn't get sent. You have to cope with either. UDP is an unreliable protocol, and code contains bugs, or unexpected exits.
NB there's no point in initializing the address and port of a DatagramPacket you're about to receive into. They will get overwritten by the source address:port of the incoming packet.

Unable to read data from InputStream

I'm trying to learn java socket programming, but I have a trouble with the read function of InputStream.
At first, I created a socket to connect to the server. After the connection is established, the server then send back the message that "the connection is established" and the read function is work fine. Then I tried to send byte message to the server, but I can't read the data from the InputStream because my program is stuck at "in.read(buf)" line. Could anyone point me out how can I solve this issue.
Socket client = new Socket("xxx.xxx.xxx.xxx", 45000);
InputStream in = client.getInputStream();
OutputStream out = client.getOutputStream();
for (int i = 0; i < 5; i++) {
byte[] buf = new byte[1024];
int data_size = in.read(buf);
String msg = "";
for (int j = 0; j < data_size; j++) {
msg += String.valueOf((char) buf[i]);
}
System.out.println(msg);
out.write(65);
out.flush();
}
InputStream.read() is a blocking call. Given the code you have provided, you are reading from the socket before writing to the socket so you will block on the first read forever. Or at least until the timeout.
#Peter Could be right. Also, closing the streams after their usage might help avoiding unexpected issues.

How to read from socket using datainputstream

I can display a single image received, but now I want to receive and write multiple images on my disk which will be sent from Android client after every 5 seconds.
Socket sock = servsock.accept();
dataInputStream = new DataInputStream(sock.getInputStream());
dataOutputStream = new DataOutputStream(sock.getOutputStream());
System.out.println("Accepted connection : " + sock);
dataInputStream = new DataInputStream(sock.getInputStream());
byte[] base64=dataInputStream.readUTF().getBytes();
byte[] arr=Base64.decodeBase64(base64);
FileOutputStream imageOutFile = new FileOutputStream("E:\\image.jpeg");
imageOutFile.write(arr);
You'll need to build a protocol between your client and the server.
If the image size is constant you just have to loop over the input-stream and keep buffering until you get the fixed number of bytes and write all the already buffered image.
Otherwise you'll need to add some metadata indicating the size of the images; e.g. you could use a simple format like this :
[size1][image1][size2][image2][size3][image3]
with [size-i] occupying a fixed amount of space and [image-i] the size of the ith image.
But above all don't be tempted to do such a naive protocol as processing an image, sleeping 5 seconds and retrieving the next one because the exact time could vary a lot between each image due to client, network or the server (your code and/or the file-system).
Little changes:
Socket sock = servsock.accept();
dataInputStream = new DataInputStream(sock.getInputStream());
dataOutputStream = new DataOutputStream(sock.getOutputStream());
System.out.println("Accepted connection : " + sock);
int imagesCount = dataInputStream.readInt();
for (int imgNum = 0; imgNum < imagesCount; imgNum++) {
int imgLen = dataInputStream.readInt();
byte[] base64 = new byte[imgLen];
dataInputStream.readFully(base64);
byte[] arr = Base64.decodeBase64(base64);
FileOutputStream imageOutFile = new FileOutputStream("E:\\image"+imgNum+".jpeg");
imageOutFile.write(arr);
}
If you are having multiple clients and a single server. Try multi-threading. Sample piece of code:
public static void main(String[] args){
try {
servSocket = new ServerSocket(xxxx);
while(true)
{
socket = servSocket.accept();
ClientNum++;
for(int i=0;i<10;i++){ //this for eg accepts 10 clients, with each client assigned an ID.
if(threads[i]==null){
sockets[i]=socket;
In your "run", you can call each of these clients by their respective ID and perform the reqd function you need. Not sure how clear this is. If needed, I can send you the entire code I have which is kinda similar to what you are doing.

Categories