I am sending a nonce to the client, however, the first client works fine. When the second client is running, it is blocked after server sent the encrypted nonce.
ReadByte Method:
private static void readByte(byte[] byteArray, InputStream byteIn, Socket socket) throws Exception{
int offset = 0;
int numRead = 0;
while (offset < byteArray.length && (numRead = byteIn.read(byteArray, offset, byteArray.length - offset)) >= 0){
offset += numRead;
}
if (offset < byteArray.length) {
System.out.println("File reception incomplete!");
}
}
EDIT ANSWER
Server:
public class Server2 {
private static final int NumberOfThreads = 5;
private static ExecutorService executorService =Executors.newScheduledThreadPool(NumberOfThreads);
private static final int port = 1111;
private static ServerSocket serverSocket;
private static final String privateKeyFile = "privateServer.der";
private static final String signedCert = "h.crt";
public static void main(String[] args) {
try{
serverSocket = new ServerSocket(port);
}catch (IOException e){
e.printStackTrace();
}
while(true){
System.out.println("Server is waiting for connection....");
try {
final Socket clientSocket = serverSocket.accept();
System.out.println("connection established....");
Runnable task = new Runnable() {
#Override
public void run() {
try {
handleClient(clientSocket);
}catch (Exception e){
e.printStackTrace();
}
}
};
executorService.execute(task);
} catch (IOException e) {
e.printStackTrace();
}
}
}
private static void handleClient(Socket clientSocket) throws Exception{
//for getting the byte input and output
OutputStream byteOut = clientSocket.getOutputStream();
InputStream byteIn = clientSocket.getInputStream();
//for getting the string input and output
PrintWriter stringOut = new PrintWriter(clientSocket.getOutputStream(),true);
BufferedReader stringIn = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
//print out client msg
System.out.println(stringIn.readLine());
stringOut.println("From Server: I am Server!");
stringOut.flush();
System.out.println("Sent to client: I am Server!");
//receive nonce from client
String nonceLen = stringIn.readLine();
byte[] nonce = new byte[Integer.parseInt(nonceLen)];
readByte(nonce,byteIn);
System.out.println("Nonce Received!");
//get private key from privateServer.der
PrivateKey privateKey = getPrivateKey();
//use private key to initialize the encryption mode
Cipher RSAEncrypt = Cipher.getInstance("RSA/ECB/PKCS1Padding");
RSAEncrypt.init(Cipher.ENCRYPT_MODE,privateKey);
//encrypt nonce and send it to the client
byte[] encryptedNonce = RSAEncrypt.doFinal(nonce);
stringOut.println(Integer.toString(encryptedNonce.length));
byteOut.write(encryptedNonce,0,encryptedNonce.length);
System.out.println(encryptedNonce);
byteOut.flush();
System.out.println("Sent to client: encrypted nonce");
}
}
Client:
public class Client2 {
private static final String server = "localhost";
private static final int port = 1111;
private static final String filePath = "medianFile.txt";
private static final String fileName = "medianFile.txt";
private static final String CAcert = "CA.crt";
public static void main(String[] args) {
try{
Socket socket = new Socket(server,port);
OutputStream byteOut = socket.getOutputStream();
InputStream byteIn = socket.getInputStream();
PrintWriter stringOut = new PrintWriter(socket.getOutputStream(),true);
BufferedReader stringIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));
stringOut.println("Please prove ur identity!");
stringOut.flush();
System.out.println("Sent to server: Please prove ur identity!");
String r1 = stringIn.readLine();
System.out.println(r1);
// send nonce
byte[] nonce = generateNonce();
if(r1.contains("I am server")){
stringOut.println(Integer.toString(nonce.length));
byteOut.write(nonce);
byteOut.flush();
System.out.println("Sent to server: nonce sent!");
}
// get encrypted nonce from server
String encryptedNonceLen = stringIn.readLine();
byte[] encryptedNonceBytes = new byte[Integer.parseInt(encryptedNonceLen)];
readByte(encryptedNonceBytes,byteIn,socket);
}
}
Related
I have implemented a file transfer program using java socket. In this program, a file is sent from the client and its then downloaded in the Server. The program works almost correctly but the problem is the length of the received byte is always greater than the byte length sent from the client. for example, I sent 678888589 bytes from the client, but when I check the length of the received file at the server, I got 678925260 bytes. And for that reason, I am getting different checksum on the server side.
Here is my code:
Client Class:
public class Client
{
final static int ServerPort = 1234;
public static final int BUFFER_SIZE = 1024 * 50;
private static byte[] buffer;
public static void main(String args[]) throws UnknownHostException, IOException
{
Scanner scn = new Scanner(System.in);
buffer = new byte[BUFFER_SIZE];
for(int i=0;i<8;i++) {
Socket s1 = new Socket(ip, ServerPort);
DataOutputStream dos1 = new DataOutputStream(s1.getOutputStream());
SendMessage message = new SendMessage(s1, "test.mp4",dos1);
Thread t = new Thread(message);
System.out.println("Adding this client to active client list");
t.start();
}
}
}
class SendMessage implements Runnable{
String file_name;
Socket s;
public final int BUFFER_SIZE = 1024 * 50;
private byte[] buffer;
DataOutputStream dos;
public SendMessage(Socket sc,String file_name,DataOutputStream dos) {
this.file_name = file_name;
this.s=sc;
buffer = new byte[BUFFER_SIZE];
this.dos = dos;
}
#Override
public void run() {
File file = new File(file_name);
try {
sendFile(file, dos);
dos.close();
while(true) {
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
public void sendFile(File file, DataOutputStream dos) throws IOException {
byte[] buffer = new byte[BUFFER_SIZE+1];
if(dos!=null&&file.exists()&&file.isFile())
{
FileInputStream input = new FileInputStream(file);
dos.writeLong(file.length());
System.out.println(file.getAbsolutePath());
int read = 0;
int totalLength = 0;
while ((read = input.read(buffer)) != -1) {
dos.write(buffer);
totalLength +=read;
System.out.println("length "+read);
}
input.close();
System.out.println("File successfully sent! "+totalLength);
}
}
}
Server Class
// Server class
public class Server
{
// Vector to store active clients
static Vector<ClientHandler> ar = new Vector<>();
// counter for clients
static int i = 0;
public static void main(String[] args) throws IOException
{
// server is listening on port 1234
ServerSocket ss = new ServerSocket(1234);
Socket s;
// running infinite loop for getting
// client request
while (true)
{
// Accept the incoming request
s = ss.accept();
System.out.println("New client request received : " + s);
// obtain input and output streams
DataInputStream dis = new DataInputStream(s.getInputStream());
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
System.out.println("Creating a new handler for this client...");
// Create a new handler object for handling this request.
ClientHandler mtch = new ClientHandler(s,"client " + i, dis, dos);
// Create a new Thread with this object.
Thread t = new Thread(mtch);
System.out.println("Adding this client to active client list");
// add this client to active clients list
ar.add(mtch);
// start the thread.
t.start();
// increment i for new client.
// i is used for naming only, and can be replaced
// by any naming scheme
i++;
}
}
}
// ClientHandler class
class ClientHandler implements Runnable
{
Scanner scn = new Scanner(System.in);
private String name;
final DataInputStream dis;
final DataOutputStream dos;
Socket s;
boolean isloggedin;
public static final int BUFFER_SIZE = 1024*50;
private byte[] buffer;
// constructor
public ClientHandler(Socket s, String name,
DataInputStream dis, DataOutputStream dos) {
this.dis = dis;
this.dos = dos;
this.name = name;
this.s = s;
this.isloggedin=true;
buffer = new byte[BUFFER_SIZE];
}
#Override
public void run() {
String received;
BufferedOutputStream out = null;
String outputFile = "out_"+this.name+".mp4";
BufferedInputStream in = null;
try {
in = new BufferedInputStream(s.getInputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
out = new BufferedOutputStream(new FileOutputStream(outputFile));
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// while (true)
// {
try
{
long length = -1;
length = dis.readLong();
if(length!=-1)System.out.println("length "+length);
// String checkSum = dis.readUTF();
// System.out.println(checkSum);
int len=0;
long totalLength = 0;
// int len = 0;
while ((len = in.read(buffer,0,BUFFER_SIZE)) > 0) {
out.write(buffer, 0, len);
totalLength+=len;
// if(len<BUFFER_SIZE)break;
// System.out.println("length "+len);
if(len<=0)break;
}
File file = new File(outputFile);
System.out.println("total length1 "+totalLength+ " dif "+(totalLength-length));
System.out.println("output length "+file.length());
} catch (IOException e) {
e.printStackTrace();
}
}
private static String checksum(String filepath, MessageDigest md) throws IOException {
// file hashing with DigestInputStream
try (DigestInputStream dis = new DigestInputStream(new FileInputStream(filepath), md)) {
while (dis.read() != -1) ; //empty loop to clear the data
md = dis.getMessageDigest();
}
// bytes to hex
StringBuilder result = new StringBuilder();
for (byte b : md.digest()) {
result.append(String.format("%02x", b));
}
return result.toString();
}
}
It would be great if anyone can tell me what I am doing wrong. also, how can I verify the checksum on serverside. Another issue is the server side code get blocked in this block.
while ((len = in.read(buffer,0,BUFFER_SIZE)) > 0) {
out.write(buffer, 0, len);
System.out.println("length "+len);
if(len<=0)break;
}
It can't break the loop unless the client is disconnected. Although the file is recieved properly.
Regards.
You made a small mistake on the client code. You were writing out the full buffer instead of what is read from the file.
while ((read = input.read(buffer)) != -1) {
dos.write(buffer,0,read);
totalLength += read;
System.out.println("length " + read);
}
I have have Tcp Server
public class SomeServer implements Runnable{
private static final int BUFFER_SIZE = 4096;
private Selector selector;
private int port;
private boolean runserver = true;
private ServerSocketChannel mySocketChannel;
private ServerSocket serverSocket;
public SomeServer(int port) {
this.port = port;
}
#Override
public void run() {
startServer();
}
private void startServer() {
try {
selector = Selector.open();
InetAddress hostIP = InetAddress.getByName("127.0.0.1");
mySocketChannel = ServerSocketChannel.open();
serverSocket = mySocketChannel.socket();
InetSocketAddress address = new InetSocketAddress(hostIP, port);
log.info("Setting up SomeServer with on {} with port {} ", hostIP, port);
serverSocket.bind(address);
mySocketChannel.configureBlocking(false);
int ops = mySocketChannel.validOps();
mySocketChannel.register(selector, ops, null);
while (runserver) {
log.info("Server running");
selector.select();
Set<SelectionKey> selectedKeys = selector.selectedKeys();
Iterator<SelectionKey> i = selectedKeys.iterator();
while (i.hasNext()) {
SelectionKey key = i.next();
if (key.isAcceptable()) {
processAcceptEvent(mySocketChannel, key);
} else if (key.isReadable()) {
processReadEvent(key);
}
i.remove();
}
}
} catch (Exception e) {
log.error("Something gone wrong in SomeServer {}", e);
}
}
private void processAcceptEvent(ServerSocketChannel mySocket, SelectionKey key) throws IOException {
log.info("Connection Accepted...");
// Accept the connection and make it non-blocking
SocketChannel myClient = mySocket.accept();
myClient.configureBlocking(false);
// Register interest in reading this channel
myClient.register(selector, SelectionKey.OP_READ);
}
private void processReadEvent(SelectionKey key) throws Exception {
log.info("Inside processReadEvent...");
// create a ServerSocketChannel to read the request
SocketChannel myClient = (SocketChannel) key.channel();
ByteBuffer myBuffer = ByteBuffer.allocate(BUFFER_SIZE);
myBuffer.order(ByteOrder.BIG_ENDIAN);
int radBytes= myClient.read(myBuffer);
if(radBytes ==-1)
return; //means connection is closed
ByteBuffer responseBuffer = clone(execute(myBuffer));
if(responseBuffer ==null){
return;
}
int byteswritten = myClient.write(responseBuffer);
log.info("bytesWritten...: {}", byteswritten);
}
public ByteBuffer execute(ByteBuffer requestBuffer) throws Exception {
final CharsetEncoder myEncoder = Charset.forName("ISO-8859-1").newEncoder();
final byte END_OF_MESSAGE_BYTE = (byte) 0x2b;
CharsetDecoder myDecoder = Charset.forName("ISO-8859-1").newDecoder();
//Process Request
final ByteBuffer processBuffer = clone(requestBuffer);
// processBuffer.flip();
int bufferSize = processBuffer.getInt();
String request = myDecoder.decode(processBuffer).toString().trim();
int requestLength=request.length();
if(requestLength<8){
log.info("Connection closed ");
return null;
}
String firstName = request.substring(0,8);
int requestBodyLength= requestLength-firstName.length();
String command = request.substring(8,requestLength-1);
processBuffer.flip();
//Build-Response
processBuffer.clear();
String response="some response";
int responselength = response.length()+firstName.length()+4;
processBuffer.putInt(responselength);
processBuffer.put(myEncoder.encode(CharBuffer.wrap(firstName)));
processBuffer.put(myEncoder.encode(CharBuffer.wrap(response)));
processBuffer.put(END_OF_MESSAGE_BYTE);
processBuffer.flip();
return processBuffer;
}
public static ByteBuffer clone(ByteBuffer original) {
if(original == null)
return null;
ByteBuffer clone = ByteBuffer.allocate(original.capacity());
original.rewind();//copy from the beginning
clone.put(original);
original.rewind();
clone.flip();
return clone;
}
}
Sending some message and except some response back
Client Side :Reading Response
public class Mycleint {
priavte SocketCahnnel mySocket;
priavte String name;
final byte END_OF_MESSAGE_BYTE = (byte) 0x2b;
public Mycleint (String name , InetSocketAddress inetAddress){
this.name=name;
mySocket = SocketChannel.open();
mySocket.connect(inetAddress);
}
private String sendRequest(String request) throws IOException {
final CharsetEncoder myEncoder = Charset.forName("ISO-8859-1").newEncoder();
int requestLength = 12 + request.length() + 1;
ByteBuffer buffer = ByteBuffer.allocate(requestLength);
buffer.order(ByteOrder.BIG_ENDIAN);
buffer.putInt(requestLength);
buffer.put(myEncoder.encode(CharBuffer.wrap(name)));
buffer.put(myEncoder.encode(CharBuffer.wrap(request)));
buffer.put();
buffer.flip();
mysocket.write(buffer);
return readResponse();
}
private String readResponse(SocketChannel mySocket) throws IOException {
CharsetDecoder myDecoder = Charset.forName("ISO-8859-1").newDecoder();
ByteBuffer responseHeaderBuf = ByteBuffer.allocate(12);
responseHeaderBuf.order(ByteOrder.BIG_ENDIAN);
int bytesRead = 0;
do {
bytesRead = mySocket.read(responseHeaderBuf);
} while (bytesRead != -1 && responseHeaderBuf.position() < 12);
if (bytesRead == -1) {
throw new IOException(" : Remote connection closed unexpectedly");
}
responseHeaderBuf.flip();
int lengthField = responseHeaderBuf.getInt();
int responseLength = lengthField - responseHeaderLength;
String responseName = myDecoder.decode(responseHeaderBuf).toString();
ByteBuffer responseBuf = ByteBuffer.allocate(responseLength);
do {
bytesRead = mySocket.read(responseBuf);
} while (bytesRead != -1 && responseBuf.position() < responseLength);
if (bytesRead == -1) {
throw new IOException(name + " : Remote connection closed unexpectedly");
}
responseBuf.flip();
if (responseBuf.get(responseBuf.limit() - 1) == END_OF_MESSAGE_BYTE) {
responseBuf.limit(responseBuf.limit() - 1);
}
String response = myDecoder.decode(responseBuf).toString();
return response;
}
}
I leave the SocketChannel open indefinitely in client side .
When I decode the response in client responseHeaderBuf.getInt(), It works correct during the first time. but second time the data get corrupted when i decode.
Also if a socket is used to send request everything works as expected,but i want to reuse the socket i created
Example, if server sent 28 processBuffer.putInt(28); client says it received responseHeaderBuf.getInt()--> 721420288 ,
Could some one help and tell me what I'm doing wrong.
So basically what I want to do is: Create a very simple multithreaded TCP server that can connect to several clients at once. This using threads and transferring messages through Byte[] and returning an echo of the message.
I have never touched anything related to server programming or TCP before, so I expect to have made a lot of mistakes. I am open for improvement and suggestions.
I made a simple Server class:
public class TCPEchoServer {
public static final int SERVERPORT = 4950;
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(SERVERPORT);
while (true) {
Socket clientSocket = serverSocket.accept();
Runnable connectionHandler = new TCPConnectionHandler(clientSocket);
new Thread(connectionHandler).start();
}
}
}
And the connection handler class:
public class TCPConnectionHandler implements Runnable {
private final Socket clientSocket;
private int msgLength = 0;
private byte[] data;
public TCPConnectionHandler(Socket clientSocket) {
this.clientSocket = clientSocket;
}
#Override
public void run() {
try {
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(clientSocket.getOutputStream());
InputStream in = clientSocket.getInputStream();
DataInputStream dis = new DataInputStream(in);
msgLength = dis.readInt();
data = new byte[msgLength];
if (msgLength > 0) {
dis.readFully(data);
}
String message = inFromClient.readLine();
System.out.println("Message recieved: " + message);
outToClient.writeBytes(String.valueOf(data));
clientSocket.close();
}
catch (IOException e) {
System.out.printf("Could not listen on port: " + clientSocket.getLocalPort());
}
}
}
And the Client class:
public class TCPEchoClient {
public static final int MYPORT = 0;
public static int BUFFSIZE = 0;
public static Socket socket;
public static final String MSG = "An Echo Message! LOL";
public static String RETURNMSG = "";
public static final byte[] messageByteArr = MSG.getBytes(Charset.forName("UTF-8"));
private static final Pattern PATTERN = Pattern.compile(
"^(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d\\d?|2[0-4]\\d|25[0-5])$");
public static void main(String[] args) throws IOException, InterruptedException {
if (args.length != 4) {
System.err.printf("ERROR: The EchoClient expects 4 parameter inputs:");
System.out.printf("IP address, Port number, message rate (msg/second).");
System.exit(1);
}
if (!isValidIP(args[0])) {
System.out.printf("ERROR: The entered IP address is not a valid IPv4 address.");
System.out.printf("Please enter a valid IPv4 address as the first argument.");
System.exit(1);
}
if (Integer.parseInt(args[1]) < 0 || Integer.parseInt(args[1]) > 65535) { //If the portnumber is negative or bigger than the highest portnumber (unsigned 16-bit integer)
System.out.printf("ERROR: The chosen portnumber is outside the available range.");
System.out.printf("Expected portnumbers: 0-65535");
System.exit(1);
}
if (Integer.parseInt(args[3]) < messageByteArr.length) {
System.out.println("Buffer size can not be smaller than the message size.");
System.out.println("Current message size: " + messageByteArr.length);
System.exit(1);
}
BUFFSIZE = Integer.parseInt(args[3]);
byte[] buf = new byte[BUFFSIZE];
DataOutputStream outToServer = null;
BufferedReader serverEcho = null;
try {
socket = new Socket(args[0], Integer.parseInt(args[1]));
outToServer = new DataOutputStream(socket.getOutputStream());
serverEcho = new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (UnknownHostException e) {
System.out.println("Unknown host address: " + args[0]);
System.exit(1);
} catch (IOException e) {
System.out.println("Could not access port " + Integer.parseInt(args[1]));
System.exit(1);
}
int msgLength = 0;
int msgStart = 0;
if (msgLength < 0) {
throw new IllegalArgumentException("Negative length not allowed.");
}
if (msgStart < 0 || msgStart >= messageByteArr.length) {
throw new IndexOutOfBoundsException("Out of bounds: " + msgStart);
}
for (int i = 1; i <= Integer.parseInt(args[2]); i++) {
outToServer.writeInt(msgLength);
if (msgLength > 0) {
outToServer.write(messageByteArr, msgStart, msgLength);
System.out.println("Message sent: " + MSG);
}
RETURNMSG = serverEcho.readLine();
System.out.println("ECHO MESSAGE: " + RETURNMSG);
}
socket.close();
}
private static boolean isValidIP(final String ip) {
return PATTERN.matcher(ip).matches();
}
}
I ran into a problem just now as well, the print outs worked before on the client and sever, but now when a message is sent. Nothing happens at all.
My main question is how I can incorporate a buffer and use it when sending and receiving messages.
You have a loop in the client that will wait args[2] times the RETURNMSG, the server will send this message only once. The RETURNMSG reading code should be outside (after) the for loop.
You should flush the buffer once you've finished writing in it.
This should be done in both client and server, since your client will wait the RETURNMSG forever depending how your protocol will evolve in the future.
I want to send multiple data type over socket.
I have that code:
when I create client, it generates public and private keys and sends the public to serve and the serve stores it.
when client wants to send message to another client, it gets his public key from the server to encrypt the message.
But when I run this code it freeze at client in dest_public_key=(PublicKey) oin.readObject()
Why it stop at here?
Why it doesn't read the PublicKey's object that the handler writes to it?
Is there any problems in streams?
public class Server {
private static final int PORT = 9001;
ServerSocket listener;
private Handler h[] = new Handler[5];
public PublicKey[] keys = new PublicKey[5];
private int clientCount = 0;
public Server() throws Exception{
System.out.println("The server is running.");
listener = new ServerSocket(PORT);
run();
}
public void run() throws Exception{
System.out.println("Waiting for a client ...");
while (true) { addClient(listener.accept());}
}
private void addClient(Socket socket) throws Exception{
h[clientCount] = new ServerHandler(this, socket,clientCount);
h[clientCount].open(clientCount);
h[clientCount].start();
clientCount++;
}
public void store(int id,PublicKey key){
keys[id]=key;}
public PublicKey getPublicKey(int id){
return keys[id]; }
public static void main(String[] args) throws Exception {
Server s = new Server();}
}
handle class
public class Handler extends Thread {
private Server server;
private Socket socket;
private int ID = -1;
private DataInputStream streamIn = null;
private DataOutputStream streamOut = null;
private ObjectInputStream obIn = null;
private ObjectOutputStream obOut = null;
public Handler(Server _server, Socket _socket, int i){
super();
server = _server;
socket = _socket;
ID = i;
}
public void run()
{ while (true)
{ try
{
int dest=streamIn.readInt();
PublicKey dest_public_key=server.getPublicKey(dest);
obOut.writeObject(dest_public_key);
obOut.flush();}}
}
public void open(int i)
{
PublicKey publick = null;
try {
streamOut = new DataOutputStream(socket.getOutputStream());
streamIn = new DataInputStream(socket.getInputStream());
obOut = new ObjectOutputStream(socket.getOutputStream());
obIn = new ObjectInputStream(socket.getInputStream());
publick=(PublicKey)obIn.readObject();
server.store(ID,publick);
streamOut.writeInt(i);
streamOut.flush();
} catch (Exception e) {
e.printStackTrace();}
}}
client class
public class Client extends implements Runnable {
DataInputStream din;
DataOutputStream dot;
ObjectInputStream oin;
ObjectOutputStream oot;
public Client() {
try {
socket = new Socket(serverAddress, 9001);
din = new DataInputStream(socket.getInputStream());
dot = new DataOutputStream(socket.getOutputStream());
oot = new ObjectOutputStream(socket.getOutputStream());
oin = new ObjectInputStream(socket.getInputStream());
RSA.generateKey();
public_key=RSA.keys.getPublic();
private_key=RSA.keys.getPrivate();
oot.writeObject(public_key);
oot.flush();
int j =din.readInt(); // read number from server
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
Client client = new Client();
PublicKey dest_public_key=null;
System.out.println("enter client that you would to send to it");
Scanner input = new Scanner( System.in );
int select = input.nextInt();
dot.writeInt(select);
dot.flush();
dest_public_key=(PublicKey) oin.readObject();
}
}
I'm trying to send a jar file over a socket to a server.
Now everything seems to be working fine but on the other side of the socket, the jar is corrupted. The files have on both sides of the socket the same length. But when I try to use the file in bukkit, the file is corrupted.
The client code:
public class Main {
private Socket connection;
private ObjectOutputStream outStream;
private static String serverAddress = ""; // the ip address
static File fileLoc = new File("C:\\Users\\Tom\\Documents\\Qubeproject\\server\\plugins");
static String fileName = "\\WorldEdit.jar";
static File file ;
static InputStream IS;
static OutputStream OS;
static byte[] msgByte = new byte[1024];
public static void main(String[] arg0){
p("Starting this shit up");
file = new File(fileLoc + fileName) ;
try {
Socket connection = connection();
IS = connection.getInputStream();
OS = connection.getOutputStream();
OS.write(msg("LOL"));
//Authenciation
IS.read(msgByte);
if(new String(msgByte).trim().equals("OK")){
p("OK");
OS.write(msg(fileName));
//sending fileName
IS.read(msgByte);
p(new String(msgByte).trim());
//confirmation
OS.write(msg("l:" + (file.length())));
byte[] fileByte = new byte[(int)(file.length())];
FileInputStream jis = new FileInputStream(file);
int count = 0;
while((count = jis.read(fileByte))>0){
OS.write(fileByte,0,count);
OS.flush();
}
OS.flush();
setByteZero(msgByte);
IS.read(msgByte);
p(new String(msgByte).trim());
//confirmation
}else{
p("Authenciation failed");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static void p (String s){
System.out.println(s);
}
private static byte[] msg(String s){
return s.getBytes();
}
private static Socket connection() throws IOException{
Socket socket = new Socket();
InetAddress ip = InetAddress.getByName(serverAddress);
InetSocketAddress address = new InetSocketAddress(ip,6969);
socket.connect(address,6969);
return socket;
}
private static byte[] setByteZero(byte[] workByte) {
for(int i=0;i < workByte.length;i++){
workByte[i] = 0;
}
return workByte;
}
the server code in bukkit
public class Checkup implements Runnable{
Server serverB;
ServerSocket server;
Socket client;
InputStream IS;
OutputStream OS;
static File destination;
byte[] msgByte = new byte[1024];
String filename;
long length;
Checkup (Server serverm){
serverB = serverm;
}
#Override
public void run() {
try{
server = new ServerSocket(6969);
}catch(Exception e){
}
try{
while(true){
client = server.accept();
IS = client.getInputStream();
OS = client.getOutputStream();
IS.read(msgByte);
if(msg(msgByte).equals("LOL")){
OS.write(msg("OK"));
IS.read(msgByte);
filename = msg(msgByte);
OS.write(msg("Q received name :" + filename));
OS.flush();
setByteZero(msgByte);
IS.read(msgByte);
length = Integer.parseInt(new String(msgByte).trim().replace("l:", ""));
OS.write(msg("Q received length :" + length));
byte[] fileByte = new byte[(int)length];
destination = new File("C:\\Users\\Quentin\\Desktop\\DE server\\plugins" + filename);
FileOutputStream fos = new FileOutputStream(destination);
int count = 0;
while((count =IS.read(fileByte))>0 ){
fos.write(fileByte);
fos.flush();
}
fos.flush();
fos.close();
OS.write(msg("Q received the jar!Bye"));
client.close();
}
}
}catch (Exception e){
e.printStackTrace();
try {
serverB.reload();
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
finally{
}}
private String msg(byte[] strByte){
return new String(strByte).trim();
}
private static byte[] msg(String s){
return s.getBytes();
}
private static byte[] setByteZero(byte[] workByte) {
for(int i=0;i < workByte.length;i++){
workByte[i] = 0;
}
return workByte;
}
#Jon pointed you to the problem, here it is spelled out and formatted.....
The following code half-ignores the count (and the count is legal to be 0 too):
while((count =IS.read(fileByte))>0 ){
fos.write(fileByte);
fos.flush();
}
fos.flush();
fos.close();
and should be written as:
while((count =IS.read(fileByte))>=0 ){
fos.write(fileByte, 0, count);
}
fos.flush();
fos.close();