Client-server message exchange - Sockets in Java - java

I'm trying to answer the clients message with an echo, but I am not figuring how to. My client sends a message, but then I reverse the papers and the program doesn't proceed (gets stuck in line
DataOutputStream out = new DataOutputStream(clientSocket.getOutputStream());
of the server). I guess it is about closing the inputstream, but when I do that, that closes the socket and I have no way to reuse it. I have managed do do this with readUTF and with socket.shutDownInput, but I want a easiest way - like close or flush, which I am not getting.
Client
public class SocketClient {
public static void main( String[] args ) throws IOException {
// Check arguments
if (args.length < 3) {
System.err.println("Argument(s) missing!");
System.err.printf("Usage: java %s host port file%n", SocketClient.class.getName());
return;
}
String host = args[0];
// Convert port from String to int
int port = Integer.parseInt(args[1]);
// Concatenate arguments using a string builder
StringBuilder sb = new StringBuilder();
for (int i = 2; i < args.length; i++) {
sb.append(args[i]);
if (i < args.length-1) {
sb.append(" ");
}
}
String text = sb.toString();
// Create client socket
Socket socket = new Socket(host, port);
System.out.printf("Connected to server %s on port %d %n", host, port);
// Create stream to send data to server
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
// Send text to server as bytes
out.writeBytes(text);
out.writeBytes("\n"); // devia meter readline a null...
System.out.println("Sent text: " + text);
System.out.println(socket.getInetAddress().getHostAddress() + " " + socket.getPort());
//out.close();
//socket.shutdownOutput(); trials...
////////////////////////////////////////////
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println("here");
// Receive data until client closes the connection
String response;
while ((response = in.readLine()) != null)
System.out.printf("Received message with content: '%s'%n", response); // here is where client doesn't proceed - he doesn't get the echo
Server
public class SocketServer {
public static void main( String[] args ) throws IOException {
// Check arguments
if (args.length < 1) {
System.err.println("Argument(s) missing!");
System.err.printf("Usage: java %s port%n", SocketServer.class.getName());
return;
}
// Convert port from String to int
int port = Integer.parseInt(args[0]);
// Create server socket
ServerSocket serverSocket = new ServerSocket(port);
System.out.printf("Server accepting connections on port %d %n", port);
// wait for and then accept client connection
// a socket is created to handle the created connection
Socket clientSocket = serverSocket.accept();
System.out.printf("Connected to client %s on port %d %n",
clientSocket.getInetAddress().getHostAddress(), clientSocket.getPort());
// Create stream to receive data from client
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
// Receive data until client closes the connection
String response;
while ((response = in.readLine()) != null)
System.out.printf("Received message with content: '%s'%n", response);
/////////////////////////////////////////////
DataOutputStream out = new DataOutputStream(clientSocket.getOutputStream()); // he doesn't reach here
System.out.println("here-serv");
System.out.println(clientSocket.getInetAddress().getHostAddress() + " " + clientSocket.getPort());
// Send text to server as bytes
out.writeBytes("echo");
I actually believe this problem has something with the readline from server, it is not getting a null - but the client sends a "\n"! Can you find my code mistake? Thanks

Related

Socket messaging between Java Client and Python Server

I try to create a Socket messager between a Java Client and Python Server. It works to send a message ("Testdata") from client to server and print it out. But after input and send a message from server to client, I get no output from client. The client 'freezes' and must be terminated.
What is the problem with my client input?
Terminal Server:
py socketServer.py
Connection from: ('127.0.0.1', 57069)
from connected user: Testdata
> Test
send data..
Terminal Client:
java socketClient
Testdata
Python-Server:
import socket
def socket_server():
host = "127.0.0.1"
port = 35100
server_socket = socket.socket()
server_socket.bind((host, port))
server_socket.listen(2)
conn, address = server_socket.accept()
print("Connection from: " + str(address))
while True:
data = conn.recv(1024).decode()
if not data:
break
print("from connected user: " + str(data))
data = input('> ')
conn.send(data.encode())
print("send data...")
conn.close()
if __name__ == '__main__':
socket_server()
Java-Client:
private static void socketTest(){
String hostname = "127.0.0.1";
int port = 35100;
try (Socket socket = new Socket(hostname, port)) {
OutputStream output = socket.getOutputStream();
PrintWriter writer = new PrintWriter(output, false);
BufferedReader input =
new BufferedReader(
new InputStreamReader(socket.getInputStream()));
Scanner in = new Scanner(System.in);
String text;
do {
text = in.nextLine();
writer.print(text);
writer.flush();
System.out.println("from server: " + input.readLine());
} while (!text.equals("exit"));
writer.close();
input.close();
socket.close();
}
}
This is because python messages are not explicitly finished with \r\n like #carlos palmas says in this answer.

Java TCP Client-Server - stuck in infinite loops in both applications [duplicate]

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.

Java socket - the server response is always null

I have to connect with a server (I donĀ“t have access to the server code) but the transmission protocol (Socket) is:
(client) --> data
ack <-- (server)
data response <-- (server)
(client) --> ack
It's assumed that the server should always respond quickly. I connect to the server, I send the data but the response is NULL and if I debug my code, an exception occurs when I catch the response:
"java.net.SocketException: Software caused connection abort: recv failed"
My code:
public static void main(String[] args){
try{
String order = "datahere";
String responseServer;
BufferedReader inFromUser = new BufferedReader( new InputStreamReader(System.in));
Socket clientSocket = new Socket();
InetSocketAddress sa = new InetSocketAddress("XXX.XX.XX.XX", 9300);
clientSocket.connect(sa,500);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
outToServer.writeBytes(order);
responseServer = inFromServer.readLine();//exception if I try to debug my code
System.out.println("From server: " + responseServer); //responseServer is NULL
clientSocket.close();
} catch (IOException ex) {
System.out.println("Error: "+ex);
}
}
That's wrong? Any idea?
I tried to disable the firewall and also add a rule for the port 9300 but the result is the same.
The client gave me an example code in Vb.Net that it's supposed to work and I try to replicate it in Java.
Code in Vb.Net:
Dim message As String = "datahere";
Try
Dim data As [Byte]() = System.Text.Encoding.ASCII.GetBytes(message)
Dim client As New TcpClient(ip, port)
Dim stream As NetworkStream = client.GetStream()
stream.Write(data, 0, data.Length)
data = New [Byte](2048) {}
Dim responseData As [String] = [String].Empty
Dim bytes As Integer = stream.Read(data, 0, data.Length)
responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes)
stream.Close()
client.Close()
Catch ex As Exception
End Try
SOLUTION:
Socket clientSocket = new Socket();
InetSocketAddress sa = new InetSocketAddress("XXX.XX.XX.XX", 9300);
clientSocket.connect(sa,500);
clientSocket.getOutputStream().write(order.getBytes("ASCII"));
byte[] data = new byte[2048];
int bytes = clientSocket.getInputStream().read(data, 0, data.length);
String responseData = new String(data, 0, bytes, "ASCII");
System.out.println("From server: " + responseData);
//Another way to catch the response:
//InputStreamReader in = new InputStreamReader(clientSocket.getInputStream());
//int data1 = in.read();
//while(data1 != -1) {
// System.out.print((char) data1);
// data1 = in.read();
//}
clientSocket.close();
Here is a translation of your VB code in java
public static void main(String[] args) throws IOException {
String order = "datahere";
// Try-with-resource statement will close your socket automatically
try (Socket clientSocket = new Socket("XXX.XX.XX.XX", 9300)) {
// Send to the sever the order encoded in ASCII
clientSocket.getOutputStream().write(order.getBytes("ASCII"));
// Sleep until we have bytes to read available
while (clientSocket.getInputStream().available() == 0) {
Thread.sleep(100L);
}
// Create the buffer of exactly the amount of bytes available without blocking
byte[] data = new byte[clientSocket.getInputStream().available()];
// Read the bytes from the server and put it into the buffer
int bytes = clientSocket.getInputStream().read(data, 0, data.length);
// Decode what has been read from the server that was encoded in ASCII
String responseData = new String(data, 0, bytes, "ASCII");
System.out.println("From server: " + responseData);
}
}
DataInputStream dis = new DataInputStream( new InputStreamReader(clientSocket.getInputStream()));
while(dis.available()>0){
//reads characters encoded with modified UTF-8
String temp = dis.readUTF();
System.out.print(temp+" ");
}
try to use a dataInputStream instead of bufferedReader and use readUTF() method in dataInputStream to read UTF characters.

How do I get the server to respond with multiple lines? (Java)

I would like to take text from a file and then send it to the server for it to capitalise before sending back to the client where it is printed out. How do I achieve this?
I can read one line and send that back to the client and I've managed to write multiple lines to the output stream (for the server to read) but I don't know what to do now..
I have a client that reads text from a file:
import java.io.*;
import java.net.*;
import java.util.Date;
public class Client
{
public static void main(String[] args)
{
try
{
// First create the input from keyboard
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Client Program");
// Next we need to find out the IP address and port number of the server
System.out.print("Enter IP Address of server: ");
String ip = input.readLine();
System.out.print("Enter port number of server: ");
String port_string = input.readLine();
// The port number needs to be an int, so convert the string to an int
int port = Integer.parseInt(port_string);
// Connect to the server
Socket sock = new Socket(ip, port);
// Create the incoming stream to read messages from
DataInputStream network = new DataInputStream(sock.getInputStream());
//Create the output stream to the client
DataOutputStream message = new DataOutputStream(sock.getOutputStream());
//Send message
//message.writeUTF("some text");
FileReader file = new FileReader("text.dat");
BufferedReader input_file = new BufferedReader(file);
// Loop until EOF
while (input_file.ready()){
// Read next line from the file
String line = input_file.readLine();
// Write line to server
message.writeUTF(line + "\n");
//System.out.println(line);
}
// Display our address
System.out.println("Address: " + sock.getInetAddress());
String line;
// Loop until the connection closes, reading from the network
while ((line = network.readUTF()) != null)
{
// Display the received message
System.out.println(line);
}
}
catch (IOException ioe)
{
// This is expected when the server closes the network connection
System.err.println("Error in I/O");
System.err.println(ioe.getMessage());
System.exit(-1);
}
}
}
And then a server that is supposed to take those strings and capitalise them:
import java.io.*;
import java.net.*;
import java.util.*;
public class Server
{
public static void main(String[] args)
{
try
{
// First create the input from the keyboard
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Server Program");
// Get the port to listen on
System.out.print("Enter port number to listen on: ");
String port_string = input.readLine();
// The port number needs to be an int, so convert the String to an int
int port = Integer.parseInt(port_string);
// Create a ServerSocket to listen on this address
ServerSocket server = new ServerSocket(port);
// Accept an incoming client connection on the server socket
Socket sock = server.accept();
// Create the output stream to the client
DataOutputStream network = new DataOutputStream(sock.getOutputStream());
//Create the incoming stream to read messages from
DataInputStream message = new DataInputStream(sock.getInputStream());
String newLine = inFromClient.readLine();
//Line to read
String line;
line = message.readUTF();
line = line.toUpperCase();
// Send message
network.writeUTF(newLine);
// Close sockets. This will cause the client to exit
sock.close();
server.close();
}
catch (IOException ioe)
{
System.err.println("Error in I/O");
System.err.println(ioe.getMessage());
System.exit(-1);
}
}
}
The problem is your server is reading the stream only once and closing the socket connection.
How will your server know you have finished sending the client data to the server socket ?
You should modify the server to listen to the port till you have finished sending the whole text. For that do something like -
String newLine;
while ( true )
newLine = inFromClient.readLine();
if (newLine.equalsIgnoreCase("END"))
{
break;
}
newLine = newLine.toUpperCase();
// Send message
network.writeUTF(newLine);
}
// Close sockets. This will cause the client to exit
sock.close();
server.close();
And from the client send "END" after all lines have been sent.
The easiest way is to use IOUtils from Apache Commons. IOUtils.readLines will return a list of Strings
Exact same question : Read/convert an InputStream to a String

Client-Server-Client communication using Sockets

I am building a small chat application in which client A wants to send something to client C with server B in between. First of all is this a correct approach for the problem??. I am able to send and receive data to and from a server but it is limited to only the client.For example if Client A sends data to server B and client C is sending data to server B then i can send data back to A and C just like an echo server. But what i want is to forward data coming from Client A to Client C via server B.
The following is the server code:
public class Server {
public static void main(String[] args) {
int port = 666; //random port number
try {
ServerSocket ss = new ServerSocket(port);
System.out.println("Waiting for a client....");
System.out.println("Got a client :) ... Finally, someone saw me through all the cover!");
System.out.println();
while(true) {
Socket socket = ss.accept();
SSocket sSocket = new SSocket(socket);
Thread t = new Thread(sSocket);
t.start();
System.out.println("Socket Stack Size-----"+socketMap.size());
}
}
catch (Exception e) { }
}
}
class SSocket implements Runnable {
private Socket socket;
public SSocket(Socket socket) {
this.socket = socket;
}
#Override
public void run() {
try {
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
DataInputStream dIn = new DataInputStream(in);
DataOutputStream dOut = new DataOutputStream(out);
String line = null;
while (true) {
line = dIn.readUTF();
System.out.println("Recievd the line----" + line);
dOut.writeUTF(line + " Comming back from the server");
dOut.flush();
System.out.println("waiting for the next line....");
}
}
catch (Exception e) { }
}
}
The client code is :
public class Client {
public static void main(String[] args) {
int serverPort = 666;
try {
InetAddress inetAdd = InetAddress.getByName("127.0.0.1");
Socket socket = new Socket(inetAdd, serverPort);
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
DataInputStream dIn = new DataInputStream(in);
DataOutputStream dOut = new DataOutputStream(out);
BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Type in something and press enter. Will send it to the server and tell ya what it thinks.");
System.out.println();
String line = null;
while (true) {
line = keyboard.readLine();
System.out.println("Wrinting Something on the server");
dOut.writeUTF(line);
dOut.flush();
line = dIn.readUTF();
System.out.println("Line Sent back by the server---" + line);
}
}
catch (Exception e) { }
}
}
When your clients connect to the server, your server creates a Socket for it, here it is Socket socket = ss.accept();, your socket variable will be holding that client.
now if you just keep adding your client socket to a arraylist in your while loop, you will have a list of clients actively connected with your server like:
after the accept:
clients = new ArrayList<DataOutputStream>();
Socket socket = ss.accept();
os = new DataOutputStream(socket.getOutputStream());
clients.add(os);
Now as you have all the clients in that clients arraylist, you can loop through it, or with some protocol define which client should i send the data after reading.
Iterator<DataOutputStream> it = clients.iterator();
while ((message = reader.readLine()) != null) { //reading
while (it.hasNext()) {
try {
DataOutputStream oss = it.next();
oss.write(message);//writing
oss.flush();
}
catch (Exception e) { }
}
}
This will loop through all the available clients in the arraylist and will send to all. you can define ways to send to only some.
For example:
maintain a ActiveClients arraylist and with some GUI interaction may be or maybe, define what all clients you want to send the message.
Then add just those clients outputStreams to ActiveClients
ActiveClients.add(clients.get(2));
or remove them, if you don't want them.
ActiveClients.remove(clients.get(2));
and now just loop through this arraylist to send the data as above.
You can create message queue for each client:
Client A sends message 'Hi' with address Client C to server B.
Server B receives message and adds it to message queue of client C.
Thread in server B which communicates with client C check message queue, retrieve message and sends it to client C.
Client C receives message.
If I am not mistaken, you must be having a problem with receiving a message from the Server or SSocket class. What happens with your code is that when you send a message from the client to the server the Server class receives your messages also gives an echo of the message in the client. However, when you send a message from the Server class, you don't get any messages in the Client Class.
To get this to work, you would have to modify your code in the following fashion:
SSocket Class
String line = null;
while (true) {
line = dIn.readUTF();
System.out.println("Recievd the line----" + line);
dOut.writeUTF(line + " Comming back from the server");
dOut.flush();
System.out.println("waiting for the next line....");
}
You should add these lines:
String Line2 = take.nextLine(); //The user types a message for the client
dOut.writeUTF(Line2 + " Comming back from the server"); //The message is sent to the client
Replace the while loop with this one and it will work fine.
while (true) {
line = dIn.readUTF(); //Takes the msg from the client
System.out.println("Recievd the line----" + line); //Prints the taken message
String Line2 = take.nextLine(); //The user types a message for the client
dOut.writeUTF(Line2 + " Comming back from the server"); //The message is sent to the client
dOut.flush();
System.out.println("waiting for the next line....");
}

Categories

Resources