How to make socket communications? - java

Recently I was looking at socket communications, and after I read few tutorials I came out with something like that.
public class Server{
public static void main(String[] args) throws IOException, InterruptedException {
ServerSocket server = new ServerSocket(9999);
Socket socket = server.accept();
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String message = "";
int ch = -1;
while((ch=in.read())!= -1 ){
message+=ch;
}
// String message = in.readLine();
System.out.println("RECEIVED "+message);
out.write("RESPONSE "+message+"\n");
out.flush();
System.out.println("NEW MESSAGE SEND");
Thread.sleep(3000);
System.out.println("CLOSE");
server.close();
}
}
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException {
Socket socket = new Socket("127.0.0.1", 9999);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
out.write("MESSAGE\n");
out.flush();
System.out.println("SEND MESSAGE");
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println(in.readLine());
socket.close();
}
}
After I run this code, Client logs "SEND MESSAGE" while server hangs on in.read() and does not receiving any message.
Can anyone help me and explain me what I'm doing wrong?

Your server is reading from the socket until end of stream. End of stream only occurs when the peer closes the connection. At that point you will be unable to send a reply. You need to reconsider your protocol. For a simple example you could read and write lines, one at a time, as you are in the client.

Related

Server's socket not outputting data unit client code stops running

I am playing around with networking and trying to send a simple message over my network using sockets in Java.
Here is the server code:
public class Server {
public static void main(String[] args) throws IOException {
String clientSentence;
String uppercaseSentence;
ServerSocket welcomeSocket = new ServerSocket(6789);
System.out.println("Server Running.");
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
clientSentence = inFromClient.readLine();
System.out.println("Client message received: " + clientSentence);
}
Here is the client code:
public class Client {
public static void main(String[] args) throws IOException {
String originalSentence;
String modifiedSentence;
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
Socket clientSocket = new Socket("localhost", 6789);
System.out.println("Please enter a sentence: ");
originalSentence = inFromUser.readLine();
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
outToServer.writeBytes(originalSentence);
System.out.println("Message Sent");
}
When I run them both and input a message into the client side, there is no confirmation on the side of the server in the console, however there is confirmation on the client side that a message has been sent. If I then end the client and stop it running, the server will output the sent message to the console them immediately throw an error.
I think it has something to do with the actual BufferedReader not actually getting the message or something?
Again I am very new to networking so any help would be much appreciated
Make sure that there is symmetry in how one connection sends data and how the other side receives the data. So, if the client is sending data via a DataOutputStream, then best to read the data in as a DataInputStream. If OTOH, you're only sending Strings, I would use a Writer such as a PrintWriter and then read with a Reader. I would send each line via println(...) and would call .flush() on the PrintWriter to ensure that the buffer sends the line when desired. For example, a simple client could look like so:
import java.util.*;
import java.net.*;
import java.io.*;
public class Client {
public static final String EXIT = "exit";
public static final int HOST_ID = 6789;
public static void main(String[] args) {
// using try-with-resources so that I close all streams when done
try (
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
Socket clientSocket = new Socket("localhost", HOST_ID);
PrintWriter out = new PrintWriter(clientSocket.getOutputStream());
) {
String input = "";
do {
System.out.print("Please enter a sentence, or \"exit\" to exit: ");
input = inFromUser.readLine();
out.println(input);
// flush the output stream to send all pending bites:
out.flush();
} while (!input.equalsIgnoreCase(EXIT));
System.out.println("All Done");
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
and the Server could look like:
import java.util.*;
import java.net.*;
import java.io.*;
public class Server {
public static void main(String[] args) {
// using try-with-resources so that I close all streams when done
try (
ServerSocket welcomeSocket = new ServerSocket(6789);
Scanner scanner = new Scanner(welcomeSocket.accept().getInputStream());
) {
System.out.println("Server Running.");
System.out.println("socket accepted");
while (scanner.hasNextLine()) {
String text = scanner.nextLine();
System.out.println("text: " + text);
System.out.println("uppercase: " + text.toUpperCase());
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}

How to give an automated response back when receiving a specific message from the client (Java, sockets)

I basically was trying to give a response back from my server if my client sends me the message "Hello mr server". However it doesn't.
Here is my code :
public class Server {
public static final int PORT = 6666;
public static void main(String[] args) throws IOException {
new Server().runServer();
}
public void runServer() throws IOException {
ServerSocket serverSocket = new ServerSocket(PORT);
System.out.println("Server up and ready for connections.....");
while (true) {
Socket socket = serverSocket.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); //for fetching data
String str = br.readLine(); //for fetching data
System.out.println("Client Data:" + str + '\n');
String dataSendingToClient = "gg";
OutputStreamWriter os = new OutputStreamWriter(socket.getOutputStream()); //for sending data
PrintWriter out = new PrintWriter(os); //for sending data
out.println(dataSendingToClient);
os.flush();
if (br.equals("hey mr server")){
OutputStreamWriter os2 = new OutputStreamWriter(socket.getOutputStream()); //for sending data
PrintWriter out2 = new PrintWriter(os); //for sending data
out2.println("hey mr client");
os.flush();
}
}
}
}
You are using br.equals("hey mr server") which will always return false, since br is not a String, but a BufferedReader
Instead you should use your already defined str variable str.equals("hey mr server")
Also note that with your current code, your server will only read one message from the client before moving on to the next connection
If you want your server to read more messages from a single client, you will need to loop until the client sends a disconnect message/the socket closes
while(true)
{
Socket socket = serverSocket.accept();
BufferedReader br = [...];
PrintWriter out = [...];
for(String message = br.readLine(); message != null; message = br.readLine())
{
//do stuff
//message is each line from the client
}
}
If you have multiple clients trying to connect, you will need to multithread the connections
I would recommend a class to enclose the connection details and use Stacks to poll if the client sent data
public static void main(String[] args) //or whatever other method you're running in
{
List<Connection> clients = new ArrayList<Connection>(); //some data structure to hold the clients
//start accepting connections
new Thread(new Runnable()
{
public void run()
{
while(true)
Connection client = new Connection(serverSocket.accept());
}
}).start();
//do something with the clients, read/write/whatever
}
private class Connection extends Runnable
{
private BufferedReader reader;
private PrintWriter writer;
private Queue<String> messages;
public Connection(Socket s)
{
reader = [...];
writer = [...];
messages = new LinkedList<String>();
}
public void run()
{
//just keep reading
while(true)
messages.add(reader.readLine();
}
public String read()
{
messages.poll();
}
public void write(String msg)
{
writer.write(msg);
writer.flush();
}
}
Note: take that as rough pseudocode

Can't send multiple messages via socket

I'm trying to make a little chat system. I have a console and a client. Right now only the client need to send messages to the console. I can connect successfully to the server, and i can send one message from client to console. The trouble begins after sending the first message. When the first message i can't send any other messages.
I don't know if it's the console that won't read the message or the client that won't send the message. In this case how could i troubleshoot this?
public class ClientMainClass {
private static Socket socket;
public static void main(String args[]) {
try {
String host = "localhost";
int port = 25000;
InetAddress address = InetAddress.getByName(host);
socket = new Socket(address, port);
Scanner scanner = new Scanner(System.in);
System.out.println("Skriv dit username:");
String name = scanner.nextLine();
System.out.println("Du er logget ind som: " + name);
String input;
do{
input = scanner.nextLine();
if (input.equalsIgnoreCase("exit")) {
System.out.println("Du forlod serveren");
socket.close();
continue;
}else {
/*OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);*/
PrintWriter printWriter = new PrintWriter(socket.getOutputStream(),true);
Date date = new Date();
String time = date.getDate()+"/"+date.getMonth()+":"+date.getHours()+":"+date.getMinutes();
//Send the message to the server
String message = time+ " - " + name + ": "+input;
printWriter.println(message);
System.out.println(message);
continue;
}
}while (!(input.equals("exit")));
} catch (Exception exception) {
exception.printStackTrace();
} finally {
//Closing the socket
try {
socket.close();
} catch(Exception e) {
e.printStackTrace();
}
}
}
}
My server:
public class Main{
private static Socket socket;
public static void main(String[] args) {
try {
int port = 25000;
ServerSocket serverSocket = new ServerSocket(port);
System.out.println("Server Started and listening to the port 25000");
while(true) {
//Reading the message from the client
socket = serverSocket.accept();
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
System.out.println(br.readLine());
}
}
catch (Exception e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch(Exception e){}
}
}
}
To be clear. I can connect to the server. I can send one message from client to console, but no more than one message.
You never read a second line. Your Server accepts a connection, reads one line from that connection and then waits for a new connection, discarding everything that might arrive at the first connection.
Your client however sends all input using the first (and only) connection, which is absolutely correct.
This specific problem can be solved like this:
while(true) {
//Reading the message from the client
socket = serverSocket.accept();
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
while(true){
System.out.println(br.readLine());
}
}
This will cause your program to print everything arriving on that first connection, but it will never accept a second connection.
In order to handle multiple clients, you need a Thread to deal with each one.

How correctly to set up server part through Java socket?

I have written server and client part, see code:
//this I run on my firt PC
public class TCPServer {
public static void main(String[] args) throws Exception{
TCPServer server = new TCPServer();
server.run();
}
public void run() throws Exception{
ServerSocket socket = new ServerSocket(6789);
Socket SOCK = socket.accept();
BufferedReader BR = new BufferedReader(new InputStreamReader(SOCK.getInputStream()));
String msg = BR.readLine();
System.out.println(msg);
if(msg != null){
PrintStream PS = new PrintStream(SOCK.getOutputStream());
PS.print("MESSAGE RECEIVED");
}
}
}
//This I run on my notebook
public class TCPClient {
public static void main(String args[]) throws Exception{
TCPClient client = new TCPClient();
client.run();
}
public void run() throws Exception{
Socket clientSocket = new Socket("192.168.88.77",6789);
PrintStream PS = new PrintStream(clientSocket.getOutputStream());
PS.print("Hello from GLADIS VLADLEN");
BufferedReader BR = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String msg = BR.readLine();
System.out.println(msg);
}
}
After running this applications nothing happens. And only after I stop Client app message is received by server part. Why this happens? I try to turn off FireWall but this don't help me.
Both the server and client are reading a line using BufferedReader#readLine(). However the PrintStream is sending characters without the line terminator.
Try calling println instead of print.

can i use multiple times (input/output)stream for different types of data transfer between two nodes [duplicate]

This question already has answers here:
Java multiple file transfer over socket
(3 answers)
Closed 6 years ago.
In this code I use multiple times of retrieve input-output data from two nodes. ... when I use more than two times input output stream it generated this type of error while running this code I need different input and output and that I want to store but unfortunate if I used more than three-time input/output stream it show error
public class Server {
private static Socket socket;
public void connect() throws IOException{
int port = 25000;
ServerSocket serverSocket = new ServerSocket(port);
System.out.println("Server Started and listening to the port 25000");
socket = serverSocket.accept();
}
//Server is running always. This is done using this while(true) loop
//Reading the message from the client
public void first() throws IOException{
connect();
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String number = br.readLine();
System.out.println("Message received from client is "+number);
//Multiplying the number by 2 and forming the return message
String returnMessage;
try
{
int numberInIntFormat = Integer.parseInt(number);
int returnValue = numberInIntFormat*2;
returnMessage = String.valueOf(returnValue) + "\n";
}
catch(NumberFormatException e)
{
//Input was not a number. Sending proper message back to
client.
returnMessage = "Please send a proper number\n";
}
second();
String e=br.readLine();System.out.println(e);
}
public void second() throws IOException{
//Sending the response back to the client.
String returnMessage="Second";
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
bw.write(returnMessage);
System.out.println("Message sent to the client is "+returnMessage);
bw.flush();
}
public static void main(String args[]) throws IOException{
Server obj = new Server();
obj.first();
// obj.second();
}public class Server {
private static Socket socket;
public void connect() throws IOException{
int port = 25000;
ServerSocket serverSocket = new ServerSocket(port);
System.out.println("Server Started and listening to the port 25000");
socket = serverSocket.accept();
}
//Server is running always. This is done using this while(true) loop
//Reading the message from the client
public void first() throws IOException{
connect();
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String number = br.readLine();
System.out.println("Message received from client is "+number);
//Multiplying the number by 2 and forming the return message
String returnMessage;
try
{
int numberInIntFormat = Integer.parseInt(number);
int returnValue = numberInIntFormat*2;
returnMessage = String.valueOf(returnValue) + "\n";
}
catch(NumberFormatException e)
{
//Input was not a number. Sending proper message back to client.
returnMessage = "Please send a proper number\n";
}
second();
String e=br.readLine();System.out.println(e);
}
public void second() throws IOException{
//Sending the response back to the client.
String returnMessage="Second";
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
bw.write(returnMessage);
System.out.println("Message sent to the client is "+returnMessage);
bw.flush();
}
public static void main(String args[]) throws IOException{
Server obj = new Server();
obj.first();
// obj.second();
}
public class client {
private static Socket socket;
//public void connect() throws UnknownHostException, IOException{
//}
public void first() throws IOException{
String host = "localhost";
int port = 25000;
InetAddress address = InetAddress.getByName(host);
socket = new Socket(address, port);
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
String number = "2";
String sendMessage = number + "\n";
bw.write(sendMessage);
bw.flush();
System.out.println("Message sent to the server : "+sendMessage);
String sendMessage1="3333";
bw.write(sendMessage1);
bw.flush();
//second();
}
public void second1() throws IOException{
//Get the return message from the server
InputStream is = socket.getInputStream();
InputStreamReader isr;
isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String message = br.readLine();
System.out.println("Message received from the server : " +message);
socket.close();
}
public static void main (String argd[]) throws IOException{
client obj1 = new client();
obj1.first();
}
-----------------------------------------
error
Message received from client is 2
Message sent to the client is Second
Exception in thread "main" java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:209)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
InputStream and OutputStream are intended to work with a single source and destination. Once you obtain an InputStream that reads from file/socket/whatever source you can use it for multiple consecutive reads. But once you are done reading from that source you need to invoke close() method on your stream.
Not closing your stream is classic reason for a memory leak in Java. In fact for that reason you ALWAYS expected to surround the usage of your source with try catch and always invoke close() method in finally statement. So to insure that it is always invoked. Further more, since close() method itself can cause an Exception, within final statement you need to surround it with its own try-catch. Starting from java 7 there is a new feature called "try with resources" that deals with this particular issue.
Please read about it here

Categories