The code below is part of a larger attempt; it tries to transfer a file's details between server and client and fails miserably. Server writes 3 elements to socket, client should receive same 3 elements. Client blocks after reading first element. What am I doing wrong?!?
public class SocketIssues {
static void client() throws Exception {
new Thread() {
#Override
public void run() {
try {
Thread.sleep(1000); // enough time for server to open its socket
Socket s = new Socket("localhost", 50001);
final DataInputStream dis = new DataInputStream(s.getInputStream());
final BufferedReader in = new BufferedReader(new InputStreamReader(dis));
System.out.println("CLIENT STARTED");
System.out.println("Operation: " + in.readLine());
System.out.println("Length: " + dis.readLong());
System.out.println("Name: " + dis.readUTF());
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
static void server() throws Exception {
ServerSocket ss = new ServerSocket(50001);
Socket s = ss.accept();
System.out.println("SERVER: client connected");
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(dos));
long l = 2194;
String nume = "The file name";
out.write("FILE1" + System.lineSeparator());
out.flush();
dos.writeLong(l);
dos.flush();
dos.writeUTF(nume);
dos.flush();
System.out.println("SERVER: done sending" + System.lineSeparator());
}
public static void main(String[] args) throws Exception {
client();
server();
}
}
Try sticking with just the DataOutputStream instead of mixing them up between data and a buffered writer and use the read/write UTF() method like you're already doing with the last object:
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
long l = 2194;
String nume = "The file name";
dos.writeUTF("FILE1");
dos.flush();
dos.writeLong(l);
dos.flush();
dos.writeUTF(nume);
dos.flush();
System.out.println("SERVER: fisier trimis" + System.lineSeparator());
then in the client:
final DataInputStream dis = new DataInputStream(s.getInputStream());
System.out.println("CLIENT STARTED");
System.out.println("Operation: " + dis.readUTF());
System.out.println("Length: " + dis.readLong());
System.out.println("Name: " + dis.readUTF());
Essentially, there's 2 layers of buffering going on. It's possible that when you call readLine() from the BufferedReader, it goes ahead and steals more bytes from the underlying stream because, well, that's what it's supposed to do. Then, when you go back to the DataInputStream and try to read an object, the preamble is gone (BufferedReader stole it), and it'll block waiting for it, eventhough there's bytes in the stream.
Related
In Java Object Serialization, you need to create the ObjectOutputStream before ObjectInputStream in both server and client side, which I did, but the client will run until it gets to the point of having to wait for data from the server (print the message "Done 3" then wait), and on the server side, the code only runs until it gets to the point of reading the first thing from the client (print "Done 1" then wait).
What else I need to do, beside creating the ObjectOutputStream before ObjectInputStream? From all the searches I've seen, they all mention the order of object creation, and in one case, they said to flush the output right after it is created (like in Example1), but that didn't work either.
Example1
ObjectOutputStream dataOut = new ObjectOutputStream(socket.getOutputStream());
dataOut.flush();
ObjectInputStream dataIn = new ObjectInputStream(socket.getInputStream());
Server
#Override
public void run() {
try {
serverSocket = new ServerSocket(4554);
serverRunning = true;
while (serverRunning) {
socket = serverSocket.accept();
ObjectOutputStream dataOut = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream dataIn = new ObjectInputStream(socket.getInputStream());
System.out.println("Done 1");
String string = dataIn.readUTF();
System.out.println("Done 2");
int number = dataIn.readInt();
System.out.println("Done 3");
dataOut.writeUTF("String from server");
System.out.println("Done 4");
dataOut.writeInt(1);
System.out.println("Done 5");
System.out.println(string + " | " + number);
}
} catch (IOException e) {
e.printStackTrace();
}
}
Client
Socket socket = new Socket("localhost", 4554);
ObjectOutputStream dataOut = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream dataIn = new ObjectInputStream(socket.getInputStream());
System.out.println("Done 1");
dataOut.writeUTF("String from client");
System.out.println("Done 2");
dataOut.writeInt(2);
System.out.println("Done 3");
String string = dataIn.readUTF();
System.out.println("Done 4");
int number = dataIn.readInt();
System.out.println("Done 5");
socket.close();
System.out.println(string + " | " + number);
//Edit:
So, if I change every writeUTF() writeInt() to writeObject(), also change every readUTF() readInt() to readObject() (adding the corresponding cast for String and int) the problem goes away, on Server and Client side. But I don't get it why this would be the case, is there an explanation for this behavior and a fix? I would use DataOuput/InputStream, but I need to send/get objects too, so DataOuput/InputStream won't help me.
This question already has answers here:
Importance of the new line "\n" in Java networking
(2 answers)
Closed 4 years ago.
I have a Client and a Server, they should have a communication in both ways. Everything worked well, client sent some information to server, and server did something with that information. Now that I tried to implement server replying to. After I've tried implementing that, both programs are now stuck in an infinite loop, waiting for information from the other side.
Here is my code for the server side:
public static void main(String[] args) throws IOException, ClassNotFoundException, SQLException {
logger.log(Level.INFO, "args[0]: {0} args[1]: {1} args[2]: {2} args[3] {3}", new Object[]{args[0], args[1], args[2], args[3]});
pathToExcel = args[0];
pathToDatabase = args[1];
numberOfAccounts = Integer.parseInt(args[2]);
portNumber = Integer.parseInt(args[3]);
listIE = new ArrayList<>();
listIE = Loader.getList(numberOfAccounts, pathToExcel);
DBBroker.createTables(pathToDatabase);
System.out.println("Check value: " + DBBroker.checkDB());
if (DBBroker.checkDB() == false) {
DBBroker.insertData();
DBBroker.insertDataBalance();
} else {
System.out.println("Data has already been inserted into the database");
}
startServer();
}
public static void startServer() throws IOException {
//ServerSocket ss = new ServerSocket(portNumber);
ServerSocket ss = new ServerSocket(portNumber);
logger.log(Level.INFO, "Server started on port number: {0}", portNumber);
try {
while (true) {
Socket clientSocket = ss.accept();
BufferedReader input = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
DataOutputStream clientOutput = new DataOutputStream(clientSocket.getOutputStream());
System.out.println("Client connected ");
//***************************************************************************
String answer = input.readLine();
//***************************************************************************
System.out.println("prosao readline");
//logger.info("Client logged in on port " +portNumber);
String[] niz = answer.split("_");
//System.out.println("niz: " +Arrays.toString(niz));
serverPortNumber = Integer.parseInt(niz[0]);
accountName = niz[1];
receiverName = niz[2];
amount = Integer.parseInt(niz[3]);
//System.out.println("Server port number: " +serverPortNumber + " accountname: " +accountName +" receiver name: " +receiverName + " amount: " +amount);
parseRequestFromClient();
System.out.println("Prosao request");
clientOutput.writeBytes("Kraj");
clientSocket.close();
}
//ss.close();
} catch (Exception e) {
e.printStackTrace();
}
}
And here is my code for the client side:
public static void main(String[] args) throws IOException {
String messageFromServer = "";
logger.log(Level.INFO, "args[0]: {0} args[1]: {1} args[2]: {2} args[3] {3}", new Object[]{args[0], args[1], args[2], args[3]});
Socket socket = new Socket("localhost", Integer.parseInt(args[0]));
//logger.info("args[0]: " +args[0] +" args[1]: " +args[1] +" args[2]: " +args[2] +" args[3] " +args[3]);
DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream());
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String dataForServer = args[0]+"_"+args[1]+"_"+args[2]+"_"+args[3];
System.out.println("Data for server: " +dataForServer);
outputStream.writeBytes(dataForServer);
System.out.println("prosao dataforserver");
//***************************************************************************
String answer = input.readLine();
//***************************************************************************
System.out.println("prosao readline");
System.out.println(answer);
socket.close();
}
Server side gets stuck at the ss.accept() line, while the Client side gets stuck at input.readLine()
I didn't add the whole project because a large portion of it is not relevant to the problem and it has a lot of code.
Your server was blocking on readLine(). It blocks for a line terminator. The client was only sending a raw string. The solution is to send a line terminator with each raw string.
The same applies when the server responds to the client.
As Simon has pointed out a printwriter would be a good choice if your message protocol is to pass line terminated strings.
I have been tasked with getting a simple TCP Client to timeout. The client works as expected, however I cannot seem to get the client to timeout when the client does not receive an input for 3 seconds or more.
I have a basic understanding of SO_TIMEOUT, but can't get it to work here.
Please help
Here is my code:
TCPClient
private static final String host = "localhost";
private static final int serverPort = 22003;
public static void main(String[] args) throws Exception
{
try
{
System.out.println("You are connected to the TCPCLient;" + "\n" + "Please enter a message:");
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
#SuppressWarnings("resource")
Socket client = new Socket(host, serverPort);
client.setSoTimeout(3000);
while(true)
{
DataOutputStream outToServer = new DataOutputStream(client.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(client.getInputStream()));
String input = inFromUser.readLine();
outToServer.writeBytes(input + "\n");
String modedInput = inFromServer.readLine();
System.out.println("You Sent: " + modedInput);
try
{
Thread.sleep(2000);
}
catch(InterruptedException e)
{
System.out.println("Slept-in");
e.getStackTrace();
}
}
}
catch(SocketTimeoutException e)
{
System.out.println("Timed Out Waiting for a Response from the Server");
}
}
setSoTimeout doesn't do what you think it does. From the Javadoc:
With this option set to a non-zero timeout, a read() call on the
InputStream associated with this Socket will block for only this
amount of time.
It's a timeout for reads from the socket, so reads() will return after 3 seconds even if there's no data. It's not a timeout for socket inactivity - i.e. the socket won't disconnect after being idle for 3 seconds.
I have the following Server and Client codes. Client tries to transfer a File say "testprgm.txt" of Size say 2000B to Server, where it saves it as "Test.txt". The problem is I can see the transfer for bytes on both the Server and Client but when I see the size of the Test.txt file after running these codes, it is ZERO.
Server Program:
import java.io.*;
import java.net.*;
public class ServerTest {
public static void main(String[] args) {
System.out.println("**********Server Program**************");
int byteRead = 0;
try {
ServerSocket serverSocket = new ServerSocket(9999);
if (!serverSocket.isBound())
System.out.println("Sever Socket not Bounded...");
else
System.out.println("Server Socket bounded to Port : " + serverSocket.getLocalPort());
Socket clientSocket = serverSocket.accept();
if (!clientSocket.isConnected())
System.out.println("Client Socket not Connected...");
else
System.out.println("Client Socket Connected : " + clientSocket.getInetAddress());
while (true) {
InputStream in = clientSocket.getInputStream();
OutputStream os = new FileOutputStream("<DESTINATION PATH>/Test.txt");
byte[] byteArray = new byte[100];
while ((byteRead = in .read(byteArray, 0, byteArray.length)) != -1) {
os.write(byteArray, 0, byteRead);
System.out.println("No. of Bytes Received : " + byteRead);
}
synchronized(os) {
os.wait(100);
}
os.close();
serverSocket.close();
//System.out.println("File Received...");
}
} catch (Exception e) {
System.out.println("Server Exception : " + e.getMessage());
e.printStackTrace();
}
}
}
Client Program :
import java.io.*;
import java.net.*;
public class Clientprgm {
public static void main(String[] args)
{
Socket socket;
try
{
socket = new Socket("SERVER IP ADDRESS>", 9999);
if(!socket.isConnected())
System.out.println("Socket Connection Not established");
else
System.out.println("Socket Connection established : "+socket.getInetAddress());
File myfile = new File("<SOURCE PATH>/testprgm.txt"); //local file path.
if(!myfile.exists())
System.out.println("File Not Existing.");
else
System.out.println("File Existing.");
byte[] byteArray = new byte[1024];
FileInputStream fis = new FileInputStream(myfile);
BufferedInputStream bis = new BufferedInputStream(fis);
OutputStream os = socket.getOutputStream();
int trxBytes =0;
while((trxBytes = bis.read(byteArray, 0, byteArray.length)) !=-1)
{
os.write(byteArray, 0, byteArray.length);
System.out.println("Transfering bytes : "+trxBytes );
}
os.flush();
bis.close();
socket.close();
System.out.println("File Transfered...");
}
catch(Exception e)
{
System.out.println("Client Exception : "+e.getMessage());
}
}
}
I would use NIO for file transfer it's shorter and more efficient. Here's client side:
try (SocketChannel sc = SocketChannel.open(new InetSocketAddress(
hostaddress, 9999));
FileChannel fc = new FileInputStream("test").getChannel()) {
fc.transferTo(0, fc.size(), sc);
}
System.out.println("File Transfered...");
Server side:
ServerSocketChannel ss = ServerSocketChannel.open();
ss.bind(new InetSocketAddress("localhost", 9999));
try (SocketChannel sc = ss.accept();
FileChannel fc = new FileOutputStream("test").getChannel()) {
fc.transferFrom(sc, 0, Long.MAX_VALUE);
}
Your server copy loop is correct, in that it uses the count returned by read() in the write() method call. Your client copy loop should do the same. It doesn't.
In any case your protocol is based on a fallacy. read() on a socket input stream will return -1 when the peer closes the connection, and not before. So putting a loop that terminates when read() returns -1 inside another loop using the same connection cannot possibly work. It seems you are trying to send multiple files over a single connection. You need to send the length ahead of each file, and only read exactly that many bytes per file.
Or else you need to close the connection after sending a single file, and remove the outer loop in the receiver.
I was trying to send plain text through Socket. So I found a post in StackOverflow, I followed it and I guess it that I did it write However, How can I accept that plain text as string in the client?
I used BufferedReader() and InputStreamReader() class, but exception has been thrown.
Exception : exception java.net.SocketException: Broken pipe
Here is the code:
Server:
OutputStreamWriter osw = new OutputStreamWriter(socket.getOutputStream(), "UTF-8");
osw.write(fileName, 0, fileName.length());
Client:
InputStream in = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String fileName = br.readLine();
br.close();
Some help would be great. :) Thank you.
Client side code:
public void soc_client() throws Exception {
long time = System.currentTimeMillis();
long totalRecieved = 0;
try {
Socket sock = new Socket("172.16.27.106", 55000);
System.out.println("Hello Client");
InputStream in = sock.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String fileName = br.readLine();
File outputFile = new File(fileName + "");
br.close(); // CLOSING BufferedReader
FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
byte[] buffer = new byte[100 * 1024];
int bytesRead = 0;
while ((bytesRead = in.read(buffer)) != -1) {
fileOutputStream.write(buffer, 0, bytesRead);
totalRecieved += bytesRead;
System.out.println("Recieved " + (totalRecieved / 1024)
+ " kilobytes in "
+ ((System.currentTimeMillis() - time) / 1000)
+ " seconds");
}
fileOutputStream.close();
sock.close();
} catch (Exception e) {
System.out.println("Exception " + e);
} finally {
System.out.println("Recieved " + totalRecieved + " bytes in "
+ (System.currentTimeMillis() - time) + "ms.");
}
}
You're reading a line but you aren't sending a line, and you aren't closing the OutputWriter either. So readLine() will block forever waiting for a line terminator or an EOS that is never coming.
Add a newline to the message.
Close the OutputWriter.
Well to use sockets to send and transfer text in client server fashion , i'm posting a simple basic code , which upon running send a HELLO WORLD response to client.
//Server Side
ServerSocket server= new ServerSocket(1166); // //1166 -port no. u can use any other too.
Socket s= server.accept(); // makes a connection whenever a client requests.
OutputStream os= socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
dos.writeUTF("Hello World");
dos.close();
// Client Side
Socket socket= new Socket("Ip address of you server" , 1166) ;
InputStream is= new InputStream();
DataInputStream dis = new DataInputStream(is);
String msg=dis.readUTF();
System.out.println(msg);
dis.close();
now after you run the code once on server computer , then run the client side code and the server will now respond you with Hello World.