I'm sending a file from Server (Java) to client (C++).
While everywhere else the data is recevied just fine. In this area, Sometimes there is "MZ[]" appended to the filename.
Here is the Receving code (C++):
else if(command == "freceive")
{
// Receive Filename
int fsize, l = 0;
WIN32_FIND_DATA FindFileData;
HANDLE hFind;
char filetoSave[BUFFER] = { 0 };
std::ostringstream response;
memset(filetoSave, '\0', BUFFER);
int fl = recv(sockfd, filetoSave, BUFFER, 0);
if (fl == SOCKET_ERROR && WSAGetLastError() == WSAECONNRESET)
{
connected = false;
}
//===================================================
std::ofstream File(filetoSave, std::ios::app | std::ios::binary);
memset(recvbuf, '\0', BUFFER);
// Recevie File
while ((fsize = recv(sockfd, recvbuf + l, sizeof(recvbuf) - l, 0)) > 0)
{
if(fsize > 0){
File.write(recvbuf, fsize);
}
}
File.close();
if(fsize == SOCKET_ERROR && WSAGetLastError() == WSAECONNRESET)
{
connected = false;
}
File.close();
if(IsFile((char*)filetoSave) == TRUE){
hFind = FindFirstFile(filetoSave , &FindFileData);
if (hFind == INVALID_HANDLE_VALUE)
{
response << "ERROR Receiving file (" << filetoSave << ") : " << GetLastError();
}
else
{
ULONGLONG FileSize = FindFileData.nFileSizeHigh;
FileSize <<= sizeof( FindFileData.nFileSizeHigh ) * 8;
FileSize |= FindFileData.nFileSizeLow;
response << "Saved : '" << filetoSave << "'\nSize : " << FileSize << " bytes.\nSaved as : " << filetoSave;
FindClose(hFind);
}
} else {
response << "Error File not found (" << filetoSave << ") : " << GetLastError();
}
EncSend(response.str().c_str());
}
and here is the part of the server which sends the filename (Java):
public static void SendRaw(Socket sock, String data)
{
try {
OutputStream outputStream = sock.getOutputStream();
DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
dataOutputStream.write(data.getBytes());
dataOutputStream.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NullPointerException ne) {
ne.printStackTrace();
}
}
Everything is going ok except the fact that the filename has MZ[] appended to it which I do not want.
Why is this happening? It has given me a headache! Where is this MZ[] coming from!?
Here's a screenshot, Note after MZ there is a wierd ascii char like [] in absolute filename, But os ignores it.
screenshot here
Related
I am trying to connect to WebSocket (currently using the chrome extension). I got it working that I receive the data. When I try to convert the integers I receive from the input stream I get totally other values. In the example below I gave in the word test as input. So do I do something wrong or do I interpret the input wrong?
Code:
#Override
public void run() {
while (true) {
try {
if(client.getInputStream().read() != -1) {
int i = client.getInputStream().read();
System.out.println("Integer: " + i);
byte b = (byte) i;
System.out.println("Byte: " + b);
char c = (char) b;
System.out.println("Char: " + c);
System.out.println("-=-=-=-=-=-=-=-=-=-=-=-");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Output:
output
A java stream returns bytes, but read returns an int so that you can get -1. So if your server is sending an int, then you need to read all of the bytes for that int and create it.
You have two ways to do this. Create a byte[] and use it as a buffer or if you're receiving 32 bit twos complement integers then you can use a DataInputStream.
An example using a buffer.
#Override
public void run() {
while (true) {
try {
byte[] buffer = new byte[4];
if(client.getInputStream().read(buffer) != -1) {
int i = (
( ( buffer[0] & 0xff ) << 24 ) |
( ( buffer[1] & 0xff ) << 16 ) |
( (buffer[2] & 0xff ) << 8) |
(buffer[3] & 0xff)
);
System.out.println("Integer: " + i);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Or you can use a DataInputStream.
DataInputStream dis = new DataInputStream(client.getInputStream());
try{
int i = dis.readInt();
} catch( EOFException e){
//end of file. This is like getting -1.
} catch( IOException e ){
//do something for an error
}
The buffer version uses the same conversion as java's DataInput.readInt, I've included it for an example. Also there is some additional checking that should be done. Even though the buffer is 4 bytes long, you could read anything from 1 to 4 bytes.
I have a code in which I read images on a network drive. i read thousands of images, but only sometimes i get following exception occasionally.
java.io.IOException: An unexpected network error occurred
at java.base/sun.nio.ch.FileDispatcherImpl.read0(Native Method)
at java.base/sun.nio.ch.FileDispatcherImpl.read(FileDispatcherImpl.java:54)
at java.base/sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:276)
at java.base/sun.nio.ch.IOUtil.read(IOUtil.java:245)
at java.base/sun.nio.ch.FileChannelImpl.read(FileChannelImpl.java:223)
at java.base/sun.nio.ch.ChannelInputStream.read(ChannelInputStream.java:65)
at java.base/sun.nio.ch.ChannelInputStream.read(ChannelInputStream.java:109)
at java.base/sun.nio.ch.ChannelInputStream.read(ChannelInputStream.java:103)
at java.base/java.io.InputStream.read(InputStream.java:205)
below is the code for which i get it
`
public static int getEPSSectionOffset(File file) throws Exception {
int result = 0;
try (InputStream inputStream =
Files.newInputStream(Paths.get(file.getAbsolutePath()),StandardOpenOption.READ);) {
byte[] fourBytes = new byte[4];
int totalBytesRead = inputStream.read(fourBytes);
if (log.isDebugEnabled())
log.debug("Total bytes read is " + totalBytesRead + " for file " + file.getPath());
if (fourBytes[0] == (byte) 0xC5 && fourBytes[1] == (byte) 0xD0 && fourBytes[2] == (byte) 0xD3
&& fourBytes[3] == (byte) 0xC6) {
totalBytesRead = inputStream.read(fourBytes);
if (log.isDebugEnabled())
log.debug("Total bytes read is " + totalBytesRead + " for file " + file.getPath());
result = makeInt(fourBytes);
}
return (result);
} catch (Exception e) {
log.error("Get EPS Section Offset - " + e.getMessage(), e);
}
return 0;
}`
I get the exception at this line- int totalBytesRead = inputStream.read(fourBytes);
You probably have a issue with the underlying network connection. This is not a type of problem you can fix, there will always be intermittent problems with networks. This means that you will have to live with it, and mitigate the impact.
Maybe something like this:
public static int getEPSSectionOffsetWithRetry(File file) {
int retryCount = 3;
for(int i=0; i < retryCount i++) {
try {
int offset = getEPSSectionOffset()
return offset;
} catch (IOException ex) {
//Maybe wait i little
}
}
throw new IOException("Retry count exceeded");
}
I'm making a Java application, and need the user to be able to upload a file to a server through PHP. The problem is that when the user uploads the file, the PHP script doesn't seem to "catch" the file.
This is the code I have so far.
PHP:
<?php
$target_path = "uploads/";
$target_path = $target_path . basename($_FILES['uploadedfile']['name']);
if (move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {
echo "1";
exit();
}
echo "0";
?>
Java:
String filename = "C:\Users\XXX\Pictures\Capture.PNG";
public void uploadFile() {
text = "";
String CrLf = "\r\n";
String filename = filepath.split("/")[filepath.split("/").length-1];
URLConnection conn = null;
OutputStream os = null;
InputStream is = null;
try {
URL con = new URL(connection);
conn = con.openConnection();
conn.setDoOutput(true);
InputStream imgIS = new FileInputStream(filepath);
byte[] imgData = new byte[imgIS.available()];
imgIS.read(imgData);
String message1 = "";
message1 += "-----------------------------4664151417711" + CrLf;
message1 += "Content-Disposition: form-data; name=\"uploadedfile\"; filename=\"Image0001.png\""
+ CrLf;
message1 += "Content-Type: image/png" + CrLf;
message1 += CrLf;
// the image is sent between the messages in the multipart message.
String message2 = "";
message2 += CrLf + "-----------------------------4664151417711--"
+ CrLf;
conn.setRequestProperty("Content-Type",
"multipart/form-data; boundary=---------------------------4664151417711");
// might not need to specify the content-length when sending chunked
// data.
conn.setRequestProperty("Content-Length", String.valueOf((message1
.length() + message2.length() + imgData.length)));
System.out.println("open os");
os = conn.getOutputStream();
System.out.println(message1);
os.write(message1.getBytes());
// SEND THE IMAGE
int index = 0;
int size = 1024;
do {
System.out.println("write:" + index);
if ((index + size) > imgData.length) {
size = imgData.length - index;
}
os.write(imgData, index, size);
index += size;
} while (index < imgData.length);
System.out.println("written:" + index);
System.out.println(message2);
os.write(message2.getBytes());
os.flush();
System.out.println("open is");
is = conn.getInputStream();
char buff = 512;
int len;
byte[] data = new byte[buff];
do {
System.out.println("READ");
len = is.read(data);
if (len > 0) {
System.out.println(new String(data, 0, len));
}
} while (len > 0);
System.out.println("DONE");
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("Close connection");
try {
os.close();
} catch (Exception e) {
}
try {
is.close();
} catch (Exception e) {
}
try {
} catch (Exception e) {
}
}
}
When getting the output from the PHP script, it always returns a "0".
I've tried a lot of different things, but nothing seems to work.
I have to make an abstaction in my software - replace direct unblockable NIO sockets ( client/server ) to software abstraction.
For example, instead of connecting via tcp client would exec openssl s_client -connect xxx.xxx.xxx.xxx . I have written a little demo, and it even works. Sometimes :(
The first trouble is that Process's streams can't be used with Selector, so I can't replace socketchannel with any other type of channel, so I have to read/write without any chance to avoid blocking.
The second one is that a protocol is a duplex binary file-transfer protocol ( binkp ), so process's buffered streams are unusabe. I've tried to avoid that converting in/out data to base64 and it works, but also sometimes.
I can't understant why it works or not sometimes. I put a piece of test code below. The first word is frame's length, but first bit is ignored. Please, tell me your guesses. Thanks.
public class BufferedSocketBase64 {
static class InToOut implements Runnable {
InputStream is;
OutputStream os;
boolean direction; //
public InToOut(InputStream is, OutputStream os, boolean direction) {
super();
this.is = is;
this.os = os;
this.direction = direction;
}
#Override
public void run() {
System.out.println(Thread.currentThread().getId() + " start "
+ ((direction) ? "encode from to" : "decode from to"));
boolean eof = false;
while (true) {
if (direction) {
// encode to base64 data
try {
int[] head = new int[2];
for (int i = 0; i < 2; i++) {
head[i] = is.read();
}
int len = (head[0] & 0xff << 8 | head[1] & 0xff) & 0x7FFF;
byte[] buf = new byte[len + 2];
buf[0] = (byte) (head[0] & 0xff);
buf[1] = (byte) (head[1] & 0xff);
for (int i = 2; i < len; i++) {
buf[i] = (byte) (is.read() & 0xff);
}
System.out.println(Thread.currentThread()
.getId() + " << " + new String(buf));
if (len > 0) {
String send = Base64Util.encode(buf, len);
send += "\n";
os.write(send.getBytes());
os.flush();
}
} catch (IOException e) {
eof = true;
}
} else { // decode from base64
try {
StringBuilder sb = new StringBuilder(1024);
byte c = 0x0a;
do {
c = (byte) is.read();
if (c >= 0 && c != 0x0a) {
sb.append(new String(new byte[] { c }));
}
} while (c != 0x0a && c >= 0);
if (sb.length() != 0) {
try {
byte[] buf = Base64Util.decode(sb.toString());
System.out.println(Thread.currentThread()
.getId() + " >> " + buf.length);
os.write(buf);
os.flush();
} catch (StringIndexOutOfBoundsException e) {
System.out
.println(Thread.currentThread().getId()
+ " error on " + sb.toString());
}
}
} catch (IOException e) {
eof = true;
}
}
if (eof) {
System.out.println(Thread.currentThread().getId() + " EOF");
break;
}
}
try {
is.close();
os.close();
} catch (IOException e) {
}
}
}
public static void main(String[] args) throws Exception {
Process proc2 = Runtime.getRuntime().exec("nc -l -p 2020");
Process proc1 = Runtime.getRuntime().exec("nc 127.0.0.1 2020");
Socket sock1 = new Socket();
sock1.connect(new InetSocketAddress("127.0.0.1", 24554), 30);
Socket sock2 = new Socket();
sock2.connect(new InetSocketAddress("127.0.0.1", 24557), 30);
new Thread(new InToOut(sock1.getInputStream(), proc1.getOutputStream(),
true)).start();
new Thread(new InToOut(proc1.getInputStream(), sock1.getOutputStream(),
false)).start();
new Thread(new InToOut(sock2.getInputStream(), proc2.getOutputStream(),
true)).start();
new Thread(new InToOut(proc2.getInputStream(), sock2.getOutputStream(),
false)).start();
}
UPDATED:
I've found right way. I uses syncchronized queries for each stream and synchronized threads to fill or erase that queries. All threads mutually blocks themselves. And it works! :)
Sorry for bother.
I've found right way. I uses syncchronized queries for each stream and synchronized threads to fill or erase that queries. All threads mutually blocks themselves. And it works! :) Sorry for bother.
How can I send string data from Java to a C++ console application under Windows? I am trying to do this:
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(proc.getOutputStream()));
String o = ...;
proc.getOutputStream().write(o.getBytes());
But I never see it on the C++ side when I do this:
ReadFile(stdin_h,buf, sizeof(buf), &bytes, 0)
ReadFile never returns.
What follows is further elaboration and sample code.
I have written a simple C++ console (Win32) application which reads from STDIN and performs actions based on input.
Now I want to write a Java application to "drive" the C++ application. The Java applicaton should:
Start the C++ application using Runtime.exec()
Write string data to the C++ app's STDIN
Repeat until it's time to die.
My Java application seems to be working, but the C++ application never receives any data on STDIN.
Here is the C++ application:
int main()
{
ofstream f("c:\\temp\\hacks.txt");
HANDLE stdin_h = GetStdHandle(STD_INPUT_HANDLE);
DWORD file_type = GetFileType(stdin_h);
if( file_type != FILE_TYPE_CHAR )
return 42;
f << "Pipe" << endl;
for( bool cont = true; cont; )
{
char buf[64*1024] = {};
DWORD bytes = 0;
if( ReadFile(stdin_h,buf, sizeof(buf), &bytes, 0) )
{
string in(buf,bytes);
cout << "Got " << in.length() << " bytes: '" << in << "'" << endl;
f << "Got " << in.length() << " bytes: '" << in << "'" << endl;
if( in.find('Q') )
cont = false;
}
else
{
cout << "Err " << GetLastError() << " while reading file" << endl;
f << "Err " << GetLastError() << " while reading file" << endl;
}
}
}
And here is the Java side:
public static void main(String[] args) {
Runtime rt =Runtime.getRuntime();
try {
Process proc = rt.exec("c:\\dev\\hacks\\x64\\debug\\hacks.exe");
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(proc.getOutputStream()));
int a = 0;
while(a < 5)
{
String o = (a == 4 ? "Q\n" : "A\n");
proc.getOutputStream().write(o.getBytes());
System.out.println("Wrote '" + o + "'");
++a;
}
try {
proc.waitFor();
// TODO code application logic here
} catch (InterruptedException ex) {
Logger.getLogger(Java_hacks.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (IOException ex) {
Logger.getLogger(Java_hacks.class.getName()).log(Level.SEVERE, null, ex);
}
}
The Java side seems to be working correctly, but I'm not ever receiving the strings on the C++ side.
Am I doing something wrong here? How can I send string data from Java to a C++ console application under Windows?
Why are you not flushing the output stream on the Java side after writing 5 strings?
proc.getOutputStream().flush();