JAVA TCP client not printing and disconnecting - java

I have a TCP server and client, but the client never prints the last system.out and disconnects from server socket.
My client message loop:
for (int i = 1; i <= Integer.parseInt(args[2]); i++) {
long messageTimeStart = System.currentTimeMillis();
outToServer.write(MSG.getBytes());
outToServer.flush();
Thread.sleep((long) messageTimePerSecond);
long messageTimeEnd = System.currentTimeMillis();
long totalMessageTime = messageTimeEnd - messageTimeStart; //Meassure total packet transfer time.
System.out.println("Message " + i + ": '" + MSG + "' sent in: " + totalMessageTime);
elapsedTime += totalMessageTime;
}
while (true) {
try {
int msgLength = serverEcho.read(buf);
if (msgLength == -1) {
break;
}
String echoMessage = new String(buf);
System.out.println("ECHO MESSAGE: " + echoMessage);
} catch (IOException e) {
System.out.println("Hot damn");
}
}
System.out.printf(args[2] + " Messages sent in: " + elapsedTime + " milliseconds.");
outToServer.close();
serverEcho.close();
socket.close();
It never gets to the four last lines for some reason. And I have no Idea why.
If it matters, here is my Server class run method:
public void run() {
try {
while (true) {
try {
inFromClient = new DataInputStream(clientSocket.getInputStream());
outToClient = new DataOutputStream(clientSocket.getOutputStream());
//InputStream in = clientSocket.getInputStream();
//DataInputStream dis = new DataInputStream(in);
int msgLength = 0;
msgLength = inFromClient.read(dataBuffer);
String message = new String(dataBuffer);
System.out.println("Message recieved: " + message);
outToClient.write(message.getBytes(), 0, msgLength);
outToClient.flush();
System.out.println("Echo message sent: " + message);
} catch (SocketException e) {
System.out.println("Connection terminated by client.");
break;
}
}
clientSocket.close();
} catch (IOException e) {
System.out.println("Could not listen on port: " + clientSocket.getLocalPort());
System.out.println("Client thread terminated.");
}
}

You already know the amount of data that the server will return to you since the server is returning the same information that the client is sending to him.
Therefore, you could try this approach:
Server
#Override
public void run() {
ServerSocket serverSocket = null;
Socket clientSocket = null;
DataInputStream inFromClient = null;
DataOutputStream outToClient = null;
try {
serverSocket = new ServerSocket(4321);
} catch (IOException ioe) {
System.out.println("Could not listen on port 4321. Cause: " + ioe);
System.exit(-1);
}
System.out.println("#Server#listening on port 4321!");
try {
clientSocket = serverSocket.accept();
} catch (IOException ioe) {
System.out.println("Accept failed on port: 4321. Cause: " + ioe);
System.exit(-1);
}
System.out.println("#Server#accepting connections on port 4321!");
try {
inFromClient = new DataInputStream(clientSocket.getInputStream());
outToClient = new DataOutputStream(clientSocket.getOutputStream());
} catch (IOException ioe) {
System.out.println("Input and output streams creation failed. Cause: " + ioe);
System.exit(-1);
}
System.out.println("#Server#created input and output streams!");
byte[] dataBuffer = new byte[1024];
try {
while (true) {
try {
int msgLength = 0;
msgLength = inFromClient.read(dataBuffer);
String message = new String(dataBuffer);
System.out.println("Message recieved: " + message);
outToClient.write(message.getBytes(), 0, msgLength);
outToClient.flush();
System.out.println("Echo message sent: " + message);
} catch (SocketException e) {
System.out.println("Connection terminated by client.");
break;
}
}
clientSocket.close();
} catch (IOException e) {
System.out.println("Could not listen on port: " + clientSocket.getLocalPort());
System.out.println("Client thread terminated.");
} finally {
try {
outToClient.close();
inFromClient.close();
clientSocket.close();
serverSocket.close();
} catch (IOException ioe) {
System.out.println("Unable to close streams and sockets. Cause: " + ioe);
System.exit(-1);
}
}
}
Client
#Override
public void run() {
String MSG = "Hello from client, mister server!";
Socket socket = null;
DataOutputStream outToServer = null;
DataInputStream inFromServer = null;
try {
socket = new Socket("localhost", 4321);
} catch (IOException ioe) {
System.out.println("Unable to connect with host: localhost. Cause: " + ioe);
System.exit(1);
}
System.out.println("#Client#connected with server localhost on port 4321!");
try {
outToServer = new DataOutputStream(socket.getOutputStream());
inFromServer = new DataInputStream(socket.getInputStream());
} catch (IOException ioe) {
System.out.println("Input and output streams creation failed. Cause: " + ioe);
System.exit(-1);
}
System.out.println("#Client#created input and output streams!");
long messageTimePerSecond = 3000;
long elapsedTime = 0;
try {
for (int it = 0; it < 5; it++) {
long messageTimeStart = System.currentTimeMillis();
outToServer.write(MSG.getBytes());
outToServer.flush();
Thread.sleep((long) messageTimePerSecond);
long messageTimeEnd = System.currentTimeMillis();
// Measure total packet transfer time.
long totalMessageTime = messageTimeEnd - messageTimeStart;
System.out.println("Message " + it + ": '" + MSG + "' sent in: " + totalMessageTime);
elapsedTime += totalMessageTime;
}
byte[] dataBuffer = new byte[1024];
String echoMessage = "";
int msgLength = 0;
int totalData = MSG.length();
boolean finish = false;
while (!finish) {
try {
msgLength = inFromServer.read(dataBuffer);
echoMessage += new String(dataBuffer, 0, msgLength);
if (echoMessage.length() == totalData) {
finish = true;
}
System.out.println("ECHO MESSAGE: " + echoMessage);
} catch (IOException e) {
System.out.println("Hot damn");
}
}
} catch (IOException | InterruptedException e) {
System.out.println("Something bad happened. Cause: " + e);
System.exit(-1);
} finally {
System.out.printf("5 Messages sent in: " + elapsedTime + " milliseconds.");
try {
inFromServer.close();
outToServer.close();
socket.close();
} catch (IOException ioe) {
System.out.println("Unable to close streams and socket. Cause: " + ioe);
System.exit(-1);
}
}
}
Both Server and Client implement Runnable and your main class can be like this:
public class ClientServerMain {
public static void main(String[] args) {
Thread server = new Thread(new Server());
server.start();
Thread client = new Thread(new Client());
client.start();
}
}

Related

Python Socket Only get information when the socket is closed

I am creating a program to play chess through the socket. My client is written in Python which is using socket to send data to the server. I receive information only when client program gets closed. Below mentioned is the client code. I am using python socket https://docs.python.org/3/library/socket.html
def youSecond(board):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('192.168.11.46', 9999))
run = True
turn = 1
new_msg = True
while run:
renderMap(board)
move = s.recv(1024).decode("utf-8")
if new_msg:
new_msg = False
print("SERVER: ", move)
players[0].play(board, move)
new_msg = True
turn +=1
renderMap(board)
print("Black machine is thinking.....")
myTurn = players[1].play(board, turn).encode("utf-8")
s.send(myTurn)
turn += 1
and my server using Java
public class ClientHandler implements Runnable {
BufferedReader reader;
Socket sock;
PrintWriter client;
public ClientHandler(Socket clientSocket, PrintWriter user) {
client = user;
try {
sock = clientSocket;
InputStreamReader isReader = new InputStreamReader(sock.getInputStream());
reader = new BufferedReader(isReader);
System.out.println("tren helllo");
} catch (Exception ex) {
ta_chat.append("Unexpected error... \n");
}
}
#Override
public void run() {
String message, connect = "Connect", disconnect = "Disconnect", chat = "Chat";
String[] data;
try {
while ((message = reader.readLine()) != null) {
System.out.println("duoi helllo");
ta_chat.append("Received: " + message + "\n");
data = message.split(":");
for (String token : data) {
ta_chat.append(token + "\n");
}
if (data[2].equals(connect)) {
tellEveryone((data[0] + ":" + data[1] + ":" + chat));
userAdd(data[0]);
} else if (data[2].equals(disconnect)) {
tellEveryone((data[0] + ":has disconnected." + ":" + chat));
userRemove(data[0]);
} else if (data[2].equals(chat)) {
tellEveryone(message);
try {
FileWriter fw = new FileWriter("C:\\Users\\Admin\\Desktop\\FixCoTuong\\moves.txt");
fw.write(data[1]);
fw.close();
} catch (Exception e) {
System.out.println(e);
}
System.out.println("sucess");
} else {
ta_chat.append("No Conditions were met. \n");
}
}
} catch (Exception ex) {
ta_chat.append("Lost a connection. \n");
ex.printStackTrace();
clientOutputStreams.remove(client);
}

Java Socket programming: Client receives " " instead of id

I'm writing a simple chat program using sockets. The program works as clients connect to the server and before they start chatting, they send their name to the server and receive an unique id on the return. This is where my code doesn't work properly.
Here's my code in Client class which sends name and receives id:
private void exchangeInformation() {
String temp;
try {
writer.println(name);
temp = reader.readLine();
System.out.println(temp);
temp = reader.readLine();
System.out.println("id has been received : "
+ temp);
this.id = Integer.parseInt(temp);
} catch (IOException e) {
System.out.println("Error Occured\n"
+ "Message: Couldn't get id from server\n"
+ "Cause: " + e.getMessage() + "\n");
}
}
And here's the code in server side which receives name and sends id:
private void exchangeInformation() {
try {
String n = reader.readLine();
setUserName(n);
System.out.println("name has been received");
writeMessage("Server: Welcome " + userName + "\n");
writeMessage(userId);
} catch (IOException e) {
System.out.println("Error Occured\n"
+ "Message: Couldn't receive client's name\n"
+ "Cause: " + e.getMessage() + "\n");
}
}
and this is writeMessage method on the server side:
public synchronized void writeMessage(String message) {
writer.println(message);
}
In both sides, writer is an object of PrintWriter and reader is an object of BufferedReader.
Well, the problem is, when I send userId to the client, client receives "" instead of proper data. the other parts of code work fine.
What is the problem and how can I fix it?
Regards
EDIT: As suggested in comments, All code:
Client class:
public class Client {
private String name;
private int id;
private boolean isConnected;
private BufferedReader reader;
//private BufferedWriter writer;
private PrintWriter writer;
private Socket socket;
public Client(String name) {
this.name = name;
}
public boolean getIsConnected() {
return isConnected;
}
public BufferedReader getReader() {
return reader;
}
public void start() {
connect();
exchangeInformation();
new ReceiveFromServer(this).start();
String output;
Scanner in = new Scanner(System.in);
while (isConnected) {
System.out.println("YOU: ");
output = in.nextLine();
writer.print(name + " : " + output);
}
try {
socket.close();
reader.close();
writer.close();
} catch (IOException e) {
System.out.println("Error Occured\n"
+ "Message: Couldn't close content(s)\n"
+ "Cause: " + e.getMessage() + "\n");
}
}
private void connect() {
System.out.println("Trying to connect to the server...\n");
try {
socket = new Socket("localhost", 4444);
} catch (IOException e) {
System.out.println("Error Occured\n"
+ "Message: User " + name + " couldn't connetct to the server\n"
+ "Cause: " + e.getMessage() + "\n");
}
try {
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
writer = new PrintWriter(socket.getOutputStream(), true);
} catch (IOException e) {
System.out.println("Error Occured\n"
+ "Message: Couldn't get socket's InputStream or OutputStream\n"
+ "Cause: " + e.getMessage());
}
System.out.println("You have cnnected to the server successfully");
}
private void exchangeInformation() {
String temp;
try {
writer.println(name);
temp = reader.readLine();
System.out.println(temp);
temp = reader.readLine();
System.out.println("id has been received : "
+ temp);
this.id = Integer.parseInt(temp);
} catch (IOException e) {
System.out.println("Error Occured\n"
+ "Message: Couldn't get id from server\n"
+ "Cause: " + e.getMessage() + "\n");
}
}
}
Server class:
public class Server {
private static Server server = new Server(4444);
private final int PORT;
private List<ClientThread> clients;
private static int counter;
private ServerSocket ss;
private boolean isListening;
private Server(int port) {
this.PORT = port;
clients = new ArrayList<>();
counter = 0;
}
public static Server getServerInstance() {
return server;
}
private int generateId() {
return ++counter;
}
public void start() {
establishConnection();
while (isListening) {
System.out.println("Server is Listening...");
Socket s = null;
try {
s = ss.accept();
} catch (IOException e) {
System.out.println("Error Occured\n"
+ "Message: An error occured while accepting a request\n"
+ "Cause: " + e.getMessage());
}
System.out.println("New connection request has been accepted\n");
ClientThread client = new ClientThread(s, this.generateId());
clients.add(client);
client.start();
}
try {
ss.close();
} catch (IOException e) {
System.out.println("Error Occured\n"
+ "Message: Couldn't close Server Socket\n"
+ "Cause: " + e.getMessage() + "\n");
}
}
public static synchronized void broadcastMessage(String message) {
Server s = getServerInstance();
for (int i = 0; i < s.clients.size(); i++) {
s.clients.get(i).writeMessage(message);
}
}
private void establishConnection() {
try {
ss = new ServerSocket(4444);
} catch (IOException e) {
System.out.println("Error Occured\n"
+ "Message: Couldn't establish server socket for connection\n"
+ "Cause: " + e.getMessage() + "\n");
}
System.out.println("Server Socket has been created Successfully\n");
isListening = true;
}
public static void removeClient(int id) {
Server s = getServerInstance();
for (int i = 0; i < s.clients.size(); i++) {
if (id == s.clients.get(i).getId()) {
s.clients.remove(i);
break;
}
}
}
}
ClientThread class:
public class ClientThread extends Thread {
private Socket socket;
private BufferedReader reader;
private PrintWriter writer;
private int userId;
private String userName;
private boolean isConnected;
public ClientThread(Socket socket, int id) {
this.socket = socket;
try {
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
writer = new PrintWriter(socket.getOutputStream(), true);
} catch (IOException e) {
System.out.println("Error Occured\n"
+ "Message: Couldn't get socket's InputStream or OutputStream\n"
+ "Cause: " + e.getMessage());
}
this.userId = id;
}
public void setUserName(String name) {
this.userName = name;
}
public void setIsConnected(boolean flag) {
isConnected = flag;
}
public BufferedReader getReader() {
return reader;
}
public int getUserId() {
return userId;
}
#Override
public void run() {
exchangeInformation();
isConnected = true;
String input;
while (isConnected) {
try {
input = reader.readLine();
if (input != null) {
if (input.equalsIgnoreCase("logout")) {
logout();
} else {
Server.broadcastMessage(input);
}
}
} catch (IOException e) {
System.out.println("Error Occured\n"
+ "Message: Couldn't receive message from client\n"
+ "Cause: " + e.getMessage() + "\n");
isConnected = false;
}
}
}
public synchronized void writeMessage(String message) {
writer.println(message);
}
public void writeMessage(int message) {
writer.println(message);
}
private void logout() {
setIsConnected(false);
try {
socket.close();
reader.close();
writer.close();
System.out.println("User " + this.userId + " has loggedout"
);
} catch (IOException e) {
System.out.println("Error Occured\n"
+ "Message: Couldn't close content(s)\n"
+ "Cause: " + e.getMessage() + "\n");
}
}
private void exchangeInformation() {
try {
String n = reader.readLine();
setUserName(n);
System.out.println("name has been received");
writeMessage("Server: Welcome " + userName + "\n");
writeMessage(userId);
} catch (IOException e) {
System.out.println("Error Occured\n"
+ "Message: Couldn't receive client's name\n"
+ "Cause: " + e.getMessage() + "\n");
}
}
}

Production ready Socket server in Java

There are many tutorials where explains about socket server/client sides, but all them are very trivial. Is there any tutorial for production ready code? I'm new in sockets. There is a client, that sends strings to server. I must create the server side. in server side I read string from client and after some manipulation saves them in db. I must response to client only IF I get string like "Error" for example. and if there are no any daya from client in 30 secs, I must close client connection, but server side must works. this is my test Client side:
public class ClientSideSocket2 {
public static void main(String[] args) {
String serverName = "localhost";
int port = 5555;
String line = "";
Socket client = null;
try {
System.out.println("Connecting to " + serverName + " on port " + port);
client = new Socket(serverName, port);
System.out.println("Just connected to " + client.getRemoteSocketAddress());
PrintWriter toServer = new PrintWriter(client.getOutputStream(), true);
BufferedReader fromServer = new BufferedReader(new InputStreamReader(client.getInputStream()));
List<String> messages = new ArrayList<>();
for (int i = 0; i < 6; i++) {
messages.add("Message " + i+1);
}
messages.add("abc");
for (int i = 0; i < messages.size(); i++) {
toServer.println(messages.get(i));
if ((line = fromServer.readLine()) != null) {
System.out.println("Responce from server: " + line);
}
}
toServer.close();
fromServer.close();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
and my server side:
public class TRSServerInterface implements Runnable {
private ServerSocket serverSocket = null;
private Socket socket = null;
boolean runner = true;
String message = "";
public TRSServerInterface() {}
#Override
public void run() { // default run method of Thread class and Runnable interface
try {
int serverPort = 5555;
ServerSocket serverSocket = new ServerSocket(serverPort);
while(true) {
System.out.println("Waiting for connection...");
socket = serverSocket.accept();
System.out.println("Connected to " + socket.getRemoteSocketAddress());
//get the input and output streams
PrintWriter toClient = new PrintWriter(socket.getOutputStream(), true);
BufferedReader fromClient = new BufferedReader(new InputStreamReader(socket.getInputStream()));
do {
message = fromClient.readLine();
System.out.println("From client > " + message);
if (message.equals("abc")) {
toClient.println("Message from server");
}
else {
toClient.println("");
}
} while (!message.equals(""));
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
// try {
// objectOut.close();
// objectIn.close();
// socket.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
}
}
}
is my solution corrent and how I can close connection with client if there are no any data in 30 secs.
There are several production ready frameworks that should be used instead of rolling your own. Socket timeouts can be used to control how long different operations are allowed to take before an exception is thrown.

Send array via a socket using ObjectInputStream

I'm trying to send the contents of a string array via a socket and then print the array items out at the other end.
I've been trying to use ObjectInputStream but have had no luck. If I'm honest I've scoured the web but I still don't really know what I'm doing.
Client
Putting objects into the array
String[] sendServer = new String [4];
{
sendServer[0] = txtUsername.getText();
sendServer[1] = dateFormat.format(date);
sendServer[2] = txtMessageOut.getText();
sendServer[3] = "I HOPE THIS WORKS!!!";
}
The socket has been created in another method and I can out, just unsure if if this is correct?
ObjectOutputStream objectStream = new ObjectOutputStream(clientSocket.getOutputStream());
objectStream.writeObject(sendServer);
System.out.println(sendServer[0]);
System.out.println(sendServer[1]);
System.out.println(sendServer[2]);
And for the server I have no clue. I've been trying with the ObjectInputStream with no luck. The socket on the server is just called socket.
Any help or pointers would be greatly appreciated.
I want to give you a code snippet. Sender and reveiver use socket to communicate. Replace Request with your data structure and eliminate the code lines you don't need.
This is sender :
private Response doUnicastTCP(Server remoteServer, Request request) throws ServerException {
Socket clientSocket = null;
ObjectOutputStream outToServer = null;
ObjectInputStream inFromServer = null;
try {
if (isStarted()) {
request.setRequestType(RequestType.UNICAST_TCP);
// LOGGER.debug("Sending " + request.getRequestType() + " "
// + request);
clientSocket = new Socket(remoteServer.getHost(), remoteServer.getUnicastTCPPort());
clientSocket.setSoTimeout(request.getTimeout());
outToServer = new ObjectOutputStream(clientSocket.getOutputStream());
inFromServer = new ObjectInputStream(clientSocket.getInputStream());
outToServer.writeObject(request);
Response response = (Response) inFromServer.readObject();
// LOGGER.debug("Received " + request.getRequestType() + " "
// + response);
if (response.getReturnValue() instanceof Exception) {
throw new ServerException((Exception) response.getReturnValue());
}
return response;
} else {
throw new ServerNotStartedException();
}
} catch (SocketTimeoutException e) {
throw new ServerException("cant execute request " + request + " on server " + remoteServer + " "
+ e.toString());
} catch (ClassNotFoundException | IOException e) {
throw new ServerException("cant execute request " + request + " on server " + remoteServer + " "
+ e.toString());
} finally {
try {
if (clientSocket != null) {
clientSocket.close();
}
} catch (IOException e) { //
LOGGER.trace("socket couldn't be closed");
}
}
}
This is receiver :
public void run() {
Request r = null;
try {
ObjectInputStream inFromClient = new ObjectInputStream(s.getInputStream());
ObjectOutputStream outToClient = new ObjectOutputStream(s.getOutputStream());
while (isStarted()) {
final Object receivedObject = inFromClient.readObject();
// LOGGER.debug("Receiving "
// + ((Request) receivedObject).getRequestType() + " "
// + receivedObject);
r = (Request) receivedObject;
processId.set(r.getProcessId());
Response rs = new Response();
rs.setRequest(r);
rs.setServerFrom(GoldenNodeServer.this);
if (getOperationBase() != null) {
try {
Object s = ReflectionUtils.callMethod(getOperationBase(), r.getMethod(), r.getParams());
rs.setReturnValue(s);
} catch (Exception e) {
rs.setReturnValue(e);
}
outToClient.writeObject(rs);
} else {
rs.setReturnValue(new NoClientProxySetException());
}
}
} catch (EOFException e) {
// LOGGER.trace("eof occured");
} catch (SocketException e) {
if (e.toString().contains("Socket closed") || e.toString().contains("Connection reset")
|| e.toString().contains("Broken pipe")) {
} else {
stop();
LOGGER.error("Error occured" + (r == null ? "" : " while processing " + r) + " ", e.toString());
}
} catch (IOException | ClassNotFoundException e) {
stop();
LOGGER.error("Error occured" + (r == null ? "" : " while processing " + r) + " ", e.toString());
} finally {
tcpProcessors.remove(this);
}
}

Sending a file with Java Sockets, losing data

I'm trying to send a file from a client to a server with Sockets in Java. It works fine when I am testing on the same machine, but when I test across different machines, I lose large chunks of data, resulting in a corrupted file. If I try to send a very small file (<20 bytes), it doesn't even reach the println inside the server's while loop.
Here is my code:
Server.java
package edu.mst.cs.sensorreceiver;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
private static final int PORT = 51111;
private static final int CHUNK_SIZE = 1024;
private static final File _downloadDir = new File("downloads/");
public static void main(String[] args) {
if (!_downloadDir.exists()) {
if (!_downloadDir.mkdirs()) {
System.err.println("Error: Could not create download directory");
}
}
Socket socket = null;
try {
ServerSocket server = new ServerSocket(PORT);
while (true) {
System.out.println("Waiting for connection...");
socket = server.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String name = in.readLine();
File file = new File(_downloadDir, name);
String size = in.readLine();
int fileSize;
try {
fileSize = Integer.parseInt(size);
} catch (NumberFormatException e) {
System.err.println("Error: Malformed file size:" + size);
e.printStackTrace();
return;
}
System.out.println("Saving " + file + " from user... (" + fileSize + " bytes)");
saveFile(file, socket.getInputStream());
System.out.println("Finished downloading " + file + " from user.");
if (file.length() != fileSize) {
System.err.println("Error: file incomplete");
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private static void saveFile(File file, InputStream inStream) {
FileOutputStream fileOut = null;
try {
fileOut = new FileOutputStream(file);
byte[] buffer = new byte[CHUNK_SIZE];
int bytesRead;
int pos = 0;
while ((bytesRead = inStream.read(buffer, 0, CHUNK_SIZE)) >= 0) {
pos += bytesRead;
System.out.println(pos + " bytes (" + bytesRead + " bytes read)");
fileOut.write(buffer, 0, bytesRead);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fileOut != null) {
try {
fileOut.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println("Finished, filesize = " + file.length());
}
}
Client.java
package edu.mst.cs.sensorreceiver;
import java.io.*;
import java.net.Socket;
public class Client {
private static final String HOSTNAME = "131.151.163.153";
private static final int PORT = 51111;
private static final int CHUNK_SIZE = 1024;
public static void main(String[] args) {
sendFile(args[0]);
}
private static void sendFile(String path) {
if (path == null) {
throw new NullPointerException("Path is null");
}
File file = new File(path);
Socket socket = null;
try {
System.out.println("Connecting to server...");
socket = new Socket(HOSTNAME, PORT);
System.out.println("Connected to server at " + socket.getInetAddress());
PrintStream out = new PrintStream(socket.getOutputStream(), true);
out.println(file.getName());
out.println(file.length());
System.out.println("Sending " + file.getName() + " (" + file.length() + " bytes) to server...");
writeFile(file, socket.getOutputStream());
System.out.println("Finished sending " + file.getName() + " to server");
} catch (IOException e) {
e.printStackTrace();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private static void writeFile(File file, OutputStream outStream) {
FileInputStream reader = null;
try {
reader = new FileInputStream(file);
byte[] buffer = new byte[CHUNK_SIZE];
int pos = 0;
int bytesRead;
while ((bytesRead = reader.read(buffer, 0, CHUNK_SIZE)) >= 0) {
outStream.write(buffer, 0, bytesRead);
outStream.flush();
pos += bytesRead;
System.out.println(pos + " bytes (" + bytesRead + " bytes read)");
}
} catch (IndexOutOfBoundsException e) {
System.err.println("Error while reading file");
e.printStackTrace();
} catch (IOException e) {
System.err.println("Error while writing " + file.toString() + " to output stream");
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
I've been working on this for hours and I have made almost no progress. I thought I had a pretty good understanding of how reading/writing from streams works, but clearly I'm missing something here.
Again, everything works perfectly when I am sending and receiving from the same machine. But if I try to send a file between two computers, even if the two are on the same LAN, I lose a lot of the data that was sent.
Can anybody figure out my problem? I've already tried everything I could think of.
You appear to be mixing chunked data and line oriented operation. I suggest you use a DataInputStream on the server, and a DataOutputStream. Starting on the client, something like
private static void sendFile(String path) {
if (path == null) {
throw new NullPointerException("Path is null");
}
File file = new File(path);
Socket socket = null;
try {
System.out.println("Connecting to server...");
socket = new Socket(HOSTNAME, PORT);
System.out.println("Connected to server at "
+ socket.getInetAddress());
try (DataOutputStream dos = new DataOutputStream(
new BufferedOutputStream(socket.getOutputStream()));) {
dos.writeUTF(file.getName());
dos.writeLong(file.length());
System.out.println("Sending " + file.getName() + " ("
+ file.length() + " bytes) to server...");
writeFile(file, dos);
System.out.println("Finished sending " + file.getName()
+ " to server");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Then on the server
socket = server.accept();
DataInputStream dis = new DataInputStream(socket.getInputStream());
String name = dis.readUTF();
File file = new File(_downloadDir, name);
long fileSize = dis.readLong();
System.out.println("Saving " + file + " from user... ("
+ fileSize + " bytes)");
In your code you mixes all that should never be mixed: (a) input/output streams, (b) PrintStream, (c) stream reader and (d) buffered reader. this hell leads to described behavior.
you should use the only object (stream) to write all your staff. and the only object (stream) to read all your staff.
I can recommend you to use either
OutputStream out = new BufferedOutputStream(socket.getOutputStream()); // for writing
InputStream in = new BufferedInputStream(socket.getInputStream()); // for reading
or
DataOutputStream out = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
DataInputStream in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
The first is more flexible, the second is simpler to use.

Categories