This is my java multithreading socketbased server, I need it to send data to the specific client who recieved data from, I don't think I need to add much, but still need guides if you will please:
public class Server {
private static int port=4444, maxConnections=0;
// Listen for incoming connections and handle them
public static void main(String[] args) {
int i=0;
try{
ServerSocket listener = new ServerSocket(port);
Socket server;
while((i++ < maxConnections) || (maxConnections == 0)){
doComms connection;
server = listener.accept();
doComms conn_c= new doComms(server);
Thread t = new Thread(conn_c);
t.start();
}
} catch (IOException ioe) {
System.out.println("IOException on socket listen: " + ioe);
ioe.printStackTrace();
}
}
}
class doComms implements Runnable {
private Socket server;
private String line,input;
doComms(Socket server) {
this.server=server;
}
public void run () {
input="";
try {
// Get input from the client
DataInputStream in = new DataInputStream (server.getInputStream());
PrintStream out = new PrintStream(server.getOutputStream());
while((line = in.readLine()) != null && !line.equals(".")) {
input=input + line;
out.println("I got:" + line);
}
// Now write to the client
System.out.println("Overall message is:" + input);
out.println("Overall message is:" + input);
server.close();
} catch (IOException ioe) {
System.out.println("IOException on socket listen: " + ioe);
ioe.printStackTrace();
}
}
}
Related
I just got started with socket programming so in order to improve my understandings of it I wanna build a multi-client chat application.
They way I intend to do it is the following:
Once the application starts you have two choices: create server or join server.
If you chose to create a server a new thread will start and host the server, then another thread will start which is gonna create a new client and automatically connect to the server just build.
And here I've encountered the following problem.
Each client can send messages to the server, but in order to keep them synchronized for all clients I was thinking to redirect the retrieved messages from the server to all clients as shown in the following diagram.
The thing is that when I try to listen and send on both client and server I get this errors.
java.net.SocketException: Connection reset
at java.base/java.net.SocketInputStream.read(SocketInputStream.java:186)
at java.base/java.net.SocketInputStream.read(SocketInputStream.java:140)
at java.base/java.net.SocketInputStream.read(SocketInputStream.java:200)
at java.base/java.io.DataInputStream.readUnsignedShort(DataInputStream.java:342)
at java.base/java.io.DataInputStream.readUTF(DataInputStream.java:594)
at java.base/java.io.DataInputStream.readUTF(DataInputStream.java:569)
at parctice.Server.lambda$main$0(Server.java:32)
at java.base/java.lang.Thread.run(Thread.java:835)
This is my server:
int port = 4444;
try {
ServerSocket serverSocket = new ServerSocket(port);
System.out.println("server starts port = " + serverSocket.getLocalSocketAddress());
while(true){
Socket socket = serverSocket.accept();
System.out.println("accepts : " + socket.getRemoteSocketAddress());
DataInputStream in = new DataInputStream(socket.getInputStream());
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
String[] message = {""};
new Thread(() -> {
try {
while(in.available() > 0){
System.out.println("SERVER > " + in.readUTF());
message[0] = in.readUTF();
}
} catch (IOException e) {
e.printStackTrace();
}
}).start();
System.err.println(message[0]);
try {
out.writeUTF(message[0] + "REDIRECTED MESSAGE");
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
and my client:
int portNumber = 4444;
System.out.println("CLIENT > Trying to connect to the server...");
try {
Socket socket = new Socket("localhost", portNumber);
DataInputStream in = new DataInputStream(socket.getInputStream());
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
new Thread(() -> {
try {
while(in.available() > 0){
System.out.println("SERVER > " + in.readUTF());
}
} catch (IOException e) {
e.printStackTrace();
}
}).start();
try {
out.writeUTF("test");
} catch (IOException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
In the end I would like to ask you guys if you think that the logic that I try to use is the right one and if not please let me know what's wrong and also if possible could you explain me why I am not being able to listen and send on both, client and server? Because when I try to send data through client and retrieve it on the server it works just fine, but I would like to accomplish both ways communication.
I've found this solution which seems to work for this scenario
First time we create the server:
private List<ClientThread> clients; // or "protected static List<ClientThread> clients;"
public List<ClientThread> getClients(){
return clients;
}
private void startServer(){
clients = new ArrayList<ClientThread>();
try {
serverSocket = new ServerSocket(PORT);
System.out.println("SERVER ON");
System.out.println("SERVER > Waiting for connections...");
// ACCEPT ALL CONNECTIONS
while (true){
try {
Socket socket = serverSocket.accept();
System.out.println("SERVER > New connection: " + socket.getRemoteSocketAddress());
ClientThread client = new ClientThread(this, socket);
Thread thread = new Thread(client);
thread.start();
clients.add(client);
} catch (IOException e) {
e.printStackTrace();
System.out.println("SERVER > Accept failed");
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
Then for each client we create a new thread
public class ClientThread implements Runnable {
private Socket socket;
private Server server;
private String clientName;
public String getClientName() {
return clientName;
}
public void setClientName(String clientName) {
this.clientName = clientName;
}
public Socket getSocket() {
return socket;
}
public void setSocket(Socket socket) {
this.socket = socket;
}
public ClientThread(Server server, Socket socket) {
this.server = server;
this.socket = socket;
}
#Override
public void run() {
try {
DataInputStream in = new DataInputStream(socket.getInputStream());
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
out.writeUTF("HI FROM SERVER");
while (!socket.isClosed()) {
try {
if (in.available() > 0) {
String input = in.readUTF();
// UNCOMMENT TO READ ON SERVER
// System.out.println("SERVER > " + input);
for (ClientThread thatClient : server.getClients()){
DataOutputStream outputParticularClient = new DataOutputStream(thatClient.getSocket().getOutputStream());
outputParticularClient.writeUTF(input + " GOT FROM SERVER");
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Client:
public void createClient(){
try {
socket = new Socket("localhost", portNumber);
// socket = new Socket(getHost(), portNumber);
DataInputStream in = new DataInputStream(socket.getInputStream());
new Thread(()->{
while(!socket.isClosed()){
try {
if (in.available() > 0){
String input = in.readUTF();
System.out.println(getUserName() + " > " + input);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
} catch (IOException e) {
e.printStackTrace();
}
}
I'm trying socket programming for the first time and try codes from https://www.oracle.com/webfolder/technetwork/tutorials/obe/java/SocketProgramming/SocketProgram.html and implement it to a frame. Clients can connect to the server, but there are some problem with my server frame like it's not responsive. And the request handler is ok for the first use per client, and not working for the next request. I notice that the handler looks like having a loop which I don't know why it's happening.
How the server react when the request made
This is how I start the server
private void btnStartActionPerformed(java.awt.event.ActionEvent evt) {
try {
server = new ServerSocket(8005);
executor = Executors.newFixedThreadPool(5);
System.out.println("Waiting for clients");
while (true) {
socket = server.accept();
Runnable worker = new RequestHandler(socket);
executor.execute(worker);
System.out.println("check executor");
}
} catch (Exception e) {
System.out.println(e);
} finally{
if(executor!=null){
executor.shutdown();
}
}
}
The request handler
public class RequestHandler implements Runnable {
private Socket socket;
ServerSocket server = null;
public RequestHandler(Socket socket) {
this.socket = socket;
}
#Override
public void run() {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
String userInput = in .readLine();
while (userInput != null) {
System.out.println("Received Message from " + Thread.currentThread().getName() + ": " + userInput);
jtaLog.append("Received Message from " + Thread.currentThread().getName() + ": " + userInput);
writer.write("You write : " + userInput);
writer.newLine();
writer.flush();
}
} catch (Exception e) {
System.out.println(e);
}
}
}
And from the client program the request made like this
private void btnSendActionPerformed(java.awt.event.ActionEvent evt) {
try {
String message = tfMessage.getText();
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out.println(message);
jtaLog.append( in .readLine() + "\n");
} catch (Exception e) {
System.out.println(e);
}
}
I am trying to implement a simple client-server application in Java.
Here is the code:
Client.java
public class Client implements Runnable {
private String hostName;
private int portNumber;
private String message;
private Socket socket;
private PrintWriter writer;
private BufferedReader reader;
public Client(String hostName, int portNumber, String message) {
this.hostName = hostName;
this.portNumber = portNumber;
this.message = message;
}
public void connect() {
try {
socket = new Socket(hostName, portNumber);
writer = new PrintWriter(socket.getOutputStream(), true);
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
writer.println(message);
} catch (UnknownHostException e) {
System.err.println("Could not resolve the host name '" + hostName + "'.");
} catch (IOException e) {
System.err.println("Could not get the I/O for the connection to '" + hostName + "'.");
}
}
private void listenForMessages() {
while (true) {
try {
System.out.println("In loop!");
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
System.err.println(e.getMessage());
}
}
}
public void run() {
connect();
listenForMessages();
}
}
Server.java
public class Server implements Runnable {
private int portNumber;
private String message;
private ServerSocket serverSocket;
private Socket clientSocket;
private PrintWriter writer;
private BufferedReader reader;
public Server(int portNumber, String message) {
this.portNumber = portNumber;
this.message = message;
}
private void listen() {
try {
serverSocket = new ServerSocket(portNumber);
} catch (IOException e) {
System.err.println(e.getMessage());
}
while (true) {
try {
clientSocket = serverSocket.accept();
writer = new PrintWriter(clientSocket.getOutputStream(), true);
reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
writer.println(message);
} catch (IOException e) {
System.err.println(e.getMessage());
break;
}
}
}
public void run() {
listen();
}
}
And this is the main class:
public class Test {
public static void main(String[] args) {
Client client = new Client("localhost", 4444, "Hello from client!");
Server server = new Server(4444, "Hello from server!");
Thread serverThread = new Thread(server);
serverThread.start();
Thread clientThread = new Thread(client);
clientThread.start();
}
}
The logic of the code is simple: both the client and the server are waiting for messages inside a while(true) loop.
The while loop inside the server's listen method executes just fine. However, inside the listenForMessages method, the loop seems to be executed only once. I only see one "In loop" printed on the screen.
Can you figure out what the problem is?
Thank you in advance!
However, inside the listenForMessages method, the loop seems to be
executed only once. I only see one "In loop" printed on the screen.
Actually it is not because the loop is executed only once it is simply because reader.readLine() will make the current thread wait until it receives an entire line and here if you check the code of the Server, it reads first and it reads in an infinite loop as reader.readLine() will only return null at the end of the stream so when the socket will be closed in this case.
If you want to implement some kind of ping-pong between the client and the server, simply read then write on one side and write and read and the other side as next:
Client code:
public void connect() {
try {
socket = new Socket(hostName, portNumber);
writer = new PrintWriter(socket.getOutputStream(), true);
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Could not resolve the host name '" + hostName + "'.");
} catch (IOException e) {
System.err.println(
"Could not get the I/O for the connection to '" + hostName + "'."
);
}
}
private void listenForMessages() {
while (true) {
try {
System.out.println("In loop!");
// Write the message for the server
writer.println(message);
// Read the message from the server
System.out.println(reader.readLine());
} catch (IOException e) {
System.err.println(e.getMessage());
}
}
}
Server code:
while (true) {
try {
clientSocket = serverSocket.accept();
writer = new PrintWriter(clientSocket.getOutputStream(), true);
reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
while (true) {
// Read the message from the client
System.out.println(reader.readLine());
// Write the message for the client
writer.println(message);
}
} catch (IOException e) {
System.err.println(e.getMessage());
break;
}
}
Output:
In loop!
Hello from client!
Hello from server!
In loop!
Hello from client!
Hello from server!
...
There are many tutorials where explains about socket server/client sides, but all them are very trivial. Is there any tutorial for production ready code? I'm new in sockets. There is a client, that sends strings to server. I must create the server side. in server side I read string from client and after some manipulation saves them in db. I must response to client only IF I get string like "Error" for example. and if there are no any daya from client in 30 secs, I must close client connection, but server side must works. this is my test Client side:
public class ClientSideSocket2 {
public static void main(String[] args) {
String serverName = "localhost";
int port = 5555;
String line = "";
Socket client = null;
try {
System.out.println("Connecting to " + serverName + " on port " + port);
client = new Socket(serverName, port);
System.out.println("Just connected to " + client.getRemoteSocketAddress());
PrintWriter toServer = new PrintWriter(client.getOutputStream(), true);
BufferedReader fromServer = new BufferedReader(new InputStreamReader(client.getInputStream()));
List<String> messages = new ArrayList<>();
for (int i = 0; i < 6; i++) {
messages.add("Message " + i+1);
}
messages.add("abc");
for (int i = 0; i < messages.size(); i++) {
toServer.println(messages.get(i));
if ((line = fromServer.readLine()) != null) {
System.out.println("Responce from server: " + line);
}
}
toServer.close();
fromServer.close();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
and my server side:
public class TRSServerInterface implements Runnable {
private ServerSocket serverSocket = null;
private Socket socket = null;
boolean runner = true;
String message = "";
public TRSServerInterface() {}
#Override
public void run() { // default run method of Thread class and Runnable interface
try {
int serverPort = 5555;
ServerSocket serverSocket = new ServerSocket(serverPort);
while(true) {
System.out.println("Waiting for connection...");
socket = serverSocket.accept();
System.out.println("Connected to " + socket.getRemoteSocketAddress());
//get the input and output streams
PrintWriter toClient = new PrintWriter(socket.getOutputStream(), true);
BufferedReader fromClient = new BufferedReader(new InputStreamReader(socket.getInputStream()));
do {
message = fromClient.readLine();
System.out.println("From client > " + message);
if (message.equals("abc")) {
toClient.println("Message from server");
}
else {
toClient.println("");
}
} while (!message.equals(""));
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
// try {
// objectOut.close();
// objectIn.close();
// socket.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
}
}
}
is my solution corrent and how I can close connection with client if there are no any data in 30 secs.
There are several production ready frameworks that should be used instead of rolling your own. Socket timeouts can be used to control how long different operations are allowed to take before an exception is thrown.
I am trying to forward a message from a client to a server and again from that server to another server. For the first time it works fine but when I type second message its say "Unexpected exception: Connection refused" why is it so?
Here is the code
Client.java
import java.net.*;
import java.io.*;
public class Client {
private Socket socket = null;
private DataInputStream console = null;
private DataOutputStream streamOut = null;
#SuppressWarnings("deprecation")
public Client(String serverName, int serverPort) {
System.out.println("Establishing connection. Please wait ...");
try {
socket = new Socket(serverName, serverPort);
System.out.println("Connected: " + socket);
start();
} catch (UnknownHostException uhe) {
System.out.println("Host unknown: " + uhe.getMessage());
} catch (IOException ioe) {
System.out.println("Unexpected exception: " + ioe.getMessage());
}
String line = "";
while (!line.equals("exit")) {
try {
line = console.readLine();
streamOut.writeUTF(line);
streamOut.flush();
} catch (IOException ioe) {
System.out.println("Sending error: " + ioe.getMessage());
}
}
}
public void start() throws IOException {
console = new DataInputStream(System.in);
streamOut = new DataOutputStream(socket.getOutputStream());
}
public void stop() {
try {
if (console != null)
console.close();
if (streamOut != null)
streamOut.close();
if (socket != null)
socket.close();
} catch (IOException ioe) {
System.out.println("Error closing ...");
}
}
public static void main(String args[]) {
#SuppressWarnings("unused")
Client client = null;
if (args.length != 2)
System.out.println("Usage: java Client host port");
else
client = new Client(args[0], Integer.parseInt(args[1]));
}
}
AuServer.java
import java.net.*;
import java.io.*;
public class AuServer {
private Socket socket = null;
private Socket publishingsocket = null;
private ServerSocket server = null;
private DataInputStream streamIn = null;
private String line = null;
private DataOutputStream streamOut = null;
public AuServer(int port) {
try {
System.out.println("Binding to port " + port + ", please wait ...");
server = new ServerSocket(port);
System.out.println("Server started: " + server);
System.out.println("Waiting for a client ...");
socket = server.accept();
System.out.println("Client accepted: " + socket);
open();
boolean done = false;
while (!done) {
try {
line = streamIn.readUTF();
System.out.println(line);
done = line.equals("exit");
} catch (IOException ioe) {
done = true;
}
forward(line, 50090);
}
close();
} catch (IOException ioe) {
System.out.println(ioe);
}
}
public void forward(String line, int port) {
try {
publishingsocket = new Socket("localhost", port);
streamOut = new DataOutputStream(publishingsocket.getOutputStream());
streamOut.writeUTF(line);
streamOut.flush();
} catch (UnknownHostException uhe) {
System.out.println("Host unknown: " + uhe.getMessage());
} catch (IOException ioe) {
System.out.println("Unexpected exception: " + ioe.getMessage());
} finally {
try {
publishingsocket.close();
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
public void open() throws IOException {
streamIn = new DataInputStream(new BufferedInputStream(
socket.getInputStream()));
}
public void close() throws IOException {
if (socket != null)
socket.close();
if (streamIn != null)
streamIn.close();
}
public static void main(String args[]) {
#SuppressWarnings("unused")
AuServer server = null;
if (args.length != 1)
System.out.println("Usage: java Server port");
else
server = new AuServer(Integer.parseInt(args[0]));
}
}
AppServer.java
import java.net.*;
import java.io.*;
public class AppServer {
private Socket socket = null;
private ServerSocket server = null;
private DataInputStream streamIn = null;
public AppServer(int port) {
try {
System.out.println("Binding to port " + port + ", please wait ...");
server = new ServerSocket(port);
System.out.println("Server started: " + server);
System.out.println("Waiting for a client ...");
socket = server.accept();
System.out.println("Client accepted: " + socket);
open();
boolean done = false;
while (!done) {
try {
String line = streamIn.readUTF();
System.out.println(line);
done = line.equals("exit");
} catch (IOException ioe) {
done = true;
}
}
close();
} catch (IOException ioe) {
System.out.println(ioe);
}
}
public void open() throws IOException {
streamIn = new DataInputStream(new BufferedInputStream(
socket.getInputStream()));
}
public void close() throws IOException {
if (socket != null)
socket.close();
if (streamIn != null)
streamIn.close();
}
public static void main(String args[]) {
#SuppressWarnings("unused")
AppServer server = null;
server = new AppServer(50090);
}
}
Pls help............
A typically socket server would require some kind of loop where in the server socket would accept incoming connections and spawn a new Thread which would be responsible for actually handling the new Socket connection, leaving the current thread free to continue processing any new incoming connections, for example...
server = new ServerSocket(port);
while (continueAccpetingConnections) {
Socket socket = server.accept();
Thread thread = new Thread(new SocketHandler(socket));
thread.start();
}
The SocketHandler would implement Runnable and provide a constructor that would accept a Socket variable.
It would then be the responsibility of the SocketHandler to actually perform the communications required by the server.
Now, if you wanted to have only one active connection, you might use
while (continueAccpetingConnections) {
Socket socket = server.accept();
process(socket);
}
Which would prevent any new connections until process returned...
Your server is written to accept exactly one connection, process it in the same thread, and then exit. If you want to keep accepting connections, do so, in a loop. If you want to handle clients concurrently, start a new thread to handle each accepted socket.