Send array via a socket using ObjectInputStream - java

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);
}
}

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");
}
}
}

JAVA TCP client not printing and disconnecting

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();
}
}

How to implement TCP connection pooling in java? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
Here, I managed to get a connection between a single server and single client but now my new hurdle is how to achieve a pool of TCP connections on client side in Java. I have gone through many sites, but at the end no fruitful solution was found. Here the class which I had used for obtaining connection to a server:
public class TCPIPCommunicator {
private final String MODULE="TCPIPCommunicator :";
//private DeviceEntity deviceEntity;
private static InetAddress inetServer = null;
private static int devicePort = -1;
private Socket clientSocket;
private BufferedOutputStream outputStream;
private BufferedInputStream inputStream;
private static boolean isLinkActive = false;
private String IP="";
public TCPIPCommunicator(String IP, int devicePort) {
this.IP=IP;
this.devicePort=devicePort;
initialize();
}
public static boolean isLinkActive(){
return isLinkActive;
}
public static void setLinkStatus(boolean status){
isLinkActive = status;
}
private void initialize() {
System.out.println(MODULE+ "Inside initialize()" );
setLinkStatus(false);
try{
inetServer = InetAddress.getByName(IP);
}catch (UnknownHostException uhe) {
System.out.println(MODULE+ "Error while creating inetaddress, Reason:"+uhe.getMessage());
}
System.out.println(MODULE+ "Connecting to - " +inetServer.getHostAddress() + ":" + devicePort);
establishConnection();
if(!isLinkActive()){
//sendNotification(TCPIPConstants.LINK_DOWN);
releaseResources();
//resumeLinkSanityHelper();
}
System.out.println(MODULE+ "out of initialize(), isLinkActive :" + isLinkActive() );
}
public boolean establishConnection(){
boolean isConnected = false;
//Get the Connection to PMS Server.
if(inetServer != null && devicePort > 0){
try{
clientSocket = new Socket(inetServer, devicePort);
clientSocket.setKeepAlive(true);
}catch(ConnectException ce){
ce.printStackTrace();
setLinkStatus(false);
System.out.println(MODULE+ "Exception in initialize() " + "Couldnot Connect Server. Reason:"+ce.getMessage());
}catch(Exception e){
e.printStackTrace();
setLinkStatus(false);
System.out.println(MODULE+ "Exception in initialize() " + "while creating socket ,Reason: " + e.getMessage());
}
//If got connection, Get the streams.
if(clientSocket != null && !clientSocket.isClosed()){
System.out.println(MODULE+ "in initialize(), Got Socket Connection." );
try{
outputStream = new BufferedOutputStream(clientSocket.getOutputStream());
}catch(Exception e){
e.printStackTrace();
outputStream=null;
setLinkStatus(false);
System.out.println(MODULE+ "Exception in initialize() while getting socket outputStream : " + e.getMessage());
}
if(outputStream != null){
try{
inputStream = new BufferedInputStream(clientSocket.getInputStream());
}catch(Exception e){
setLinkStatus(false);
System.out.println(MODULE+ "Exception in initialize() " + "while getting socket inputStream : " + e.getMessage());
}
setLinkStatus(true);
}
if(outputStream != null && inputStream != null){
isConnected = true;
}
}else{
System.out.println(MODULE+ "in initialize(), Connection is closed or null." );
setLinkStatus(false);
}
}
return isConnected;
}
public int writeData(byte[] msg){
int retValue = -1;
try{
if(isLinkActive() && (outputStream !=null)){
System.out.println(MODULE+ "Writting data ::::" + new String(msg)+ "::::");
outputStream.write(msg);// ed
outputStream.flush();
retValue = 1;
}else{
System.out.println(MODULE+ " in writeData() link is down so status:" + retValue );
}
}catch(Exception e){
e.printStackTrace();
retValue = -1;
System.out.println(MODULE+ "Exception in write() < message to be sent was = " + new String(msg) + " > : " + e.getMessage());
}
if(retValue == -1 && isLinkActive()){
setLinkStatus(false);
//sendNotification(TCPIPConstants.LINK_DOWN);
//releaseResources();
//resumeLinkSanityHelper();
}
System.out.println(MODULE+ " in writeData() Write status for ::"+ new String(msg) + ":: -->" +retValue);
return retValue;
}
public String readData() {
System.out.println(MODULE+"\tInside readDAta");
String response = null;
int bytesReceived=-1;
byte[] readBuffer = new byte[1024];
try{
long timetoread = System.currentTimeMillis();
if(inputStream == null || !(isLinkActive())){
System.out.println(MODULE+"Inputstream is null or link is down, returning null");
return null;
}
try{
System.out.println("Waiting to read data");
bytesReceived = inputStream.read(readBuffer);
System.out.println(MODULE+"# Byte Receieved #" + bytesReceived);
}catch(Exception e){
e.printStackTrace();
System.out.println(MODULE+"Error in readData() , Reason:"+e.getMessage());
if(isLinkActive()){
setLinkStatus(false);
//sendNotification(TCPIPConstants.LINK_DOWN);
releaseResources();
//resumeLinkSanityHelper();
}
}
if(bytesReceived > 0){
response = new String(readBuffer,0,bytesReceived); // ed
timetoread = System.currentTimeMillis() - timetoread;
System.out.println(MODULE + "Total Bytes Received: " + bytesReceived);
System.out.println(MODULE+ "Total Time Taken : " + timetoread);
System.out.println(MODULE+ "Length of data received : " + response.length());
System.out.println(MODULE+ "Data Received : ####" + response + "####");
}else{
////////// HERE MEANS TCP CONNECTION STATUS WILL CLOSE_WAIT
////////// SO RELEASING CONNECTION.
System.out.println(MODULE+ " Releasing Resource. bytesReceived is <= 0 : Total Bytes Received :"+ bytesReceived );
if(isLinkActive()){
setLinkStatus(false);
//sendNotification(TCPIPConstants.LINK_DOWN);
releaseResources();
//resumeLinkSanityHelper();
}
System.out.println(MODULE+ " Resource has been released.");
}
}catch(Exception e){
e.printStackTrace();
System.out.println(MODULE+ "In catch : Data Received : ####" + response + "####");
System.out.println(MODULE+ "Exception in readdata() : " + e);
}finally{
readBuffer=null;
}
return response;
}
public void releaseResources(){
System.out.println(MODULE+ "Releasing Resources....");
try{
if(clientSocket !=null)
clientSocket.close();
}catch(Exception e){
System.out.println(MODULE+ "In releaseResources() :Error closing socket."+e.getMessage());
}
try{
if(inputStream !=null )
inputStream.close();
}catch(Exception e){
System.out.println(MODULE+ "In releaseResources() :Error closing inputStream."+e.getMessage());
}
try{
if(outputStream != null){
outputStream.close();
}
}catch(Exception e){
System.out.println(MODULE+ "in releaseResources() :Error closing outputStream.");
}
System.out.println(MODULE + "Resources Relased...");
}
}
Here establishConnection() method will be establish the connection to the server.
Note: I was thinking on using ThreadPoolExecutor, but as the requirement is for synchronous, I dropped this idea of using it.
The sample code is like below,I use a Map ,the key is "host-port" ,and the value is a LinkedList containing the sockets related to the same url.
public class SocketPool{
Map<String,LinkedList<Socket>> sockets;
public boolean establishConnection(String inetServer , int devicePort){
boolean result = false;
try {
Socket clientSocket = new Socket(inetServer, devicePort);
String socketKey = inetServer + "-" + devicePort;
if(clientSocket.isConnected()&&sockets.containsKey(socketKey)){
sockets.get(socketKey).add(clientSocket);
}else if(clientSocket.isConnected()&&!sockets.containsKey(socketKey)){
LinkedList<Socket> socketSet = new LinkedList<Socket>();
socketSet.add(clientSocket);
sockets.put(socketKey, socketSet);
}
result = true;
} catch (UnknownHostException e) {
result = false;
} catch (IOException e) {
result = false;
}
return result;
}
public Socket fetchSocket(String inetServer , int devicePort){
String socketKey = inetServer + "-" + devicePort;
Socket clientSocket =null;
if(sockets.containsKey(socketKey)&&!sockets.get(socketKey).isEmpty()){
clientSocket = sockets.get(socketKey).removeLast();
int size = sockets.get(socketKey).size();
if(size==0){
sockets.remove(socketKey);
}
}
return clientSocket;
}
//other functions
}
You can create a variable Set<Socket> to store all the client Sockets you created. Every time you connect to the server socket you can put the client
socket into this set. This set works as the pool.

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