I am working on multi chat in java. I'm kinda new to this socket thing.
There is a problem with my code but I can't find it. I think the problem is in clientSocket.getInputStream(); . I inserted System.out.println before and after this statement. I can't see the second one. It seems that client can connect to port but cannot get inputs from server. If you can help me, I really would be thankful. It has been 3 hours but still I can't find the problem
ClientSide.java
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class ClientSide
{
public Socket clientSocket;
public ObjectOutputStream outStream;
public ObjectInputStream inStream;
public String receiveMessage=null,sendMessage=null;
public GuiScreen gui;
public void run()
{
try
{
clientSocket = new Socket("localhost", 2222);
inStream = new ObjectInputStream(clientSocket.getInputStream());
outStream = new ObjectOutputStream(clientSocket.getOutputStream());
outStream.flush();
while(true)
{
try
{
receiveMessage = (String)inStream.readObject();
gui.appendMessage(receiveMessage);
}
catch(ClassNotFoundException classNot)
{System.err.println("data received in unknown format");}
}
}
catch(UnknownHostException unknownHost)
{System.err.println("You are trying to connect to an unknown host!");}
catch(IOException ioException)
{ioException.printStackTrace();}
}
public String readMessage()
{
String text = "";
try
{
text = (String)inStream.readObject();
}
catch (ClassNotFoundException | IOException e)
{e.printStackTrace();}
return text;
}
public void sendMessage(String msg)
{
try
{
outStream.writeObject(msg);
outStream.flush();
}
catch(IOException ioException){ioException.printStackTrace();}
}
public ClientSide()
{}
private void showGui()
{
gui = new GuiScreen(this,"Client Side");
}
public static void main(String[] args)
{
ClientSide client = new ClientSide();
client.showGui();
client.run();
}
}
MultiCheatServer.java
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class MultiChatServer
{
public static ClientThread[] clientThreads = new ClientThread[10];
public static int portNumber = 2222;
public static ServerSocket serverSocket = null;
public static Socket clientSocket = null;
public static void openPort()
{
try
{
serverSocket = new ServerSocket(portNumber);
}
catch (IOException e)
{e.printStackTrace();}
}
public static void connectToClients()
{
while(true)
{
try
{
clientSocket = serverSocket.accept();
}
catch (IOException e)
{e.printStackTrace();}
for(int i = 0; i<=9; ++i)
{
if(clientThreads[i] == null)
{
clientThreads[i] = new ClientThread(clientSocket,clientThreads);
clientThreads[i].start();
break;
}
}
}
}
public static void main(String[] args)
{
openPort();
connectToClients();
}
}
ClientThread.java
import java.io.DataInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintStream;
import java.net.Socket;
public class ClientThread extends Thread
{
public ObjectInputStream inStream = null;
public ObjectOutputStream outStream = null;
public Socket clientSocket;
public ClientThread[] clientThreads;
public ClientThread (Socket cSocket,ClientThread[] cThreads)
{
clientSocket = cSocket;
clientThreads = cThreads;
}
public void sendMessage(String msg)
{
try
{
outStream.writeObject(msg);
outStream.flush();
}
catch (IOException e)
{e.printStackTrace();}
}
public String readMessage()
{
String text = null;
try
{
text = (String)inStream.readObject();
}
catch (ClassNotFoundException | IOException e)
{e.printStackTrace();}
return text;
}
public void run()
{
String text;
String name;
try
{
inStream = new ObjectInputStream(clientSocket.getInputStream());
outStream= new ObjectOutputStream(clientSocket.getOutputStream());
outStream.flush();
sendMessage("Name:\n");
name = readMessage().trim();
sendMessage("type /quit if you want to quit\n");
for(int i = 0 ; i <=9 ; ++i)
if(clientThreads[i]!=null && clientThreads[i]!=this)
clientThreads[i].sendMessage(name + "has come\n");
while(true)
{
text = readMessage() ;
if(text.startsWith("/quit"))
break;
for(int i = 0; i<=9; ++i)
if(clientThreads[i] != null)
clientThreads[i].sendMessage("<" + name + ">" + text);
}
for(int i = 0 ;i<=9; ++i)
if(clientThreads[i]!=null && clientThreads[i]!=this)
clientThreads[i].sendMessage(name + " has disconnected\n");
sendMessage("Bye\n");
inStream.close();
outStream.close();
for(int i = 0;i<=9;++i)
if(clientThreads[i]==this)
clientThreads[i] = null;
}
catch (IOException e)
{e.printStackTrace();}
}
}
One problem I see is that you have to decide who creates the input stream first, the server or the client.
ObjectInputStream tries to read a serialization header in its constructor, and if the output stream has not written it yet it will wait. Now both client and server are waiting for the other to "speak" first.
Related
i am trying to create a simple chat app using java sockets, the server is threaded, when a client connects its socket is added to an ArrayList, so that i can send to all in that list.
the problem is when 3 clients are connected, the for loop that sends doesn't work properly, for ex : client 0 sends to both 1 and 2 but client 2 doesn't send to anyone :(
The server and the ClientHandler :
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Scanner;
public class MainServer {
private static int portnumber = 6968;
static ArrayList <ClientHandler> allClients = new ArrayList<>();
public static void main(String[] args) throws Exception {
// init
// server works by default on localhost
ServerSocket serversocket = new ServerSocket(portnumber);
int clientNo = 0;
System.out.println("server is running on port : " + portnumber);
while (true) {
// creating a socket for each connection
Socket clientsocket = null;
try {
// receiving incoming requests from users/clients
clientsocket = serversocket.accept();
// input and output from client
PrintWriter out = new PrintWriter(clientsocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(clientsocket.getInputStream()));
// create a threads
ClientHandler ch = new ClientHandler(clientsocket, "Client#" + clientNo, in, out);
// adding to the clientList
allClients.add(ch);
System.out.println(ch.clientName + " has joined");
Thread clientThread = new Thread(ch);
clientThread.start();
// decrease when user leaves
clientNo++;
} catch (Exception e) {
clientsocket.close();
e.printStackTrace();
System.exit(1);
//out.close();
//in.close();
//clientSocket.close();
//serverSocket.close();
}
}
}
}
// handle client requests
public class ClientHandler implements Runnable{
public String clientName;
public Socket clientsocket = null;
public boolean active = false;
private BufferedReader inp;
private PrintWriter out;
private final String EXIT_STR = "exit";
public Scanner clientSc = new Scanner(System.in);
public ClientHandler(Socket socket, String name, BufferedReader inp, PrintWriter out) {
this.clientsocket = socket;
this.clientName = name;
this.inp = inp;
this.out = out;
// active when the thread is created
this.active = true;
}
#Override
public void run() {
// getting the output temp
String recivedMsg = "";
while (true) {
try {
recivedMsg = inp.readLine();
System.out.println(recivedMsg);
// check for ctrl+C
if (recivedMsg.equals(this.EXIT_STR)){
// send to all
System.out.println(this.clientName + " exits");
// close the connection and break
this.active = false;
this.clientsocket.close();
// bye
break;
}
// send to all except me
for (ClientHandler client : MainServer.allClients){
if (!client.clientName.equals(this.clientName)){
client.out.println(this.clientName + ":" + recivedMsg);
client.out.flush();
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
try {
// clean
this.clientsocket.close();
this.inp.close();
this.out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
The client :
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
public class Client {
private String hostName;
private int portNumber;
// set connction and server
public PrintWriter out = null;
public BufferedReader in = null;
public Socket clientSocket = null;
Client(String hostName, int port) {
this.hostName = hostName;
this.portNumber = port;
// setting the connction
this.setConnection();
}
private void setConnection () {
try {
this.clientSocket = new Socket(this.hostName, this.portNumber);
this.out = new PrintWriter(this.clientSocket.getOutputStream(), true);
this.in = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
}
public void sendMessageToServer(String msg) {
//System.out.println("The msg is : " + msg);
out.println(msg);
}
public String readMessage() {
String outputMsg = "";
try {
outputMsg = in.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return outputMsg;
}
// shit cleaning
public void closeSession(){
try {
this.out.close();
this.in.close();
this.clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
System.out.println("Session has been terminated!");
}
public static void main(String args[]) throws IOException{
// init
String host = "localhost";
int port = 6968;
Client newClient = new Client(host, port);
// // send a message
Scanner sc = new Scanner(System.in);
Thread sendMsg = new Thread(new Runnable() {
#Override
public void run() {
while (true) {
try {
String userInput = sc.nextLine();
newClient.sendMessageToServer(userInput);
if (userInput.equals("exit")) {
System.exit(1);
}
} catch (Exception e) {
System.exit(1);
}
}
}
});
Thread getMsg = new Thread(new Runnable() {
#Override
public void run() {
while (true) {
String msgRead = "";
try {
msgRead = newClient.readMessage();
System.out.println(msgRead);
} catch (Exception e) {
System.exit(1);
}
}
}
});
sendMsg.start();
getMsg.start();
}
}
I think the problem is here :
// send to all except me
for (ClientHandler client : MainServer.allClients){
if (!client.clientName.equals(this.clientName)){
client.out.println(this.clientName + ":" + recivedMsg);
client.out.flush();
break;
}
}
The fix is straightforward: remove the break statement from the loop where you think the problem is.
This break statement causes the loop through all the ClientHandlers to stop as soon as it sends the message to one client. You don't want this: you want this loop to keep going and send the message to all clients other than the one that wrote the message.
I have to do a project in Java for an exam which has to have multi-client sockets.
We have some example code for sockets from our teacher - and I modified it a bit. The problem is that it only receives data once, and then it stops. I found that out by printing the received data into the console.
So here's my the code:
Server.java
package socket;
import database.models.PersoanaEntity;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static final int PORT = 27015;
public void start() {
new Thread(() -> {
try {
ServerSocket serverSocket = new ServerSocket(PORT);
Socket clientSocket = null;
boolean isClose = false;
System.out.println("Server is running");
while (!isClose) {
clientSocket = serverSocket.accept();
new Thread(new ServerThread(clientSocket)).start();
}
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}).start();
}
}
ServerThread.java
package socket;
import database.models.PersoanaEntity;
import org.json.JSONObject;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
public class ServerThread extends Thread{
private Socket socket = null;
private ObjectInputStream in = null;
private ObjectOutputStream out = null;
PersoanaEntity loggedInPerson = new PersoanaEntity();
public ServerThread(Socket socket) {
this.socket = socket;
try {
//For receiving and sending data
this.in = new ObjectInputStream(socket.getInputStream());
this.out = new ObjectOutputStream(socket.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
try {
String received = this.in.readObject().toString();
System.out.println(received);
JSONObject jsonObject = new JSONObject(received);
execute(received);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
private void execute(String message) {
JSONObject jo = new JSONObject(message);
ProcessInput pi = new ProcessInput();
pi.processInput(jo, this.out);
}
}
ProcessInput.java
package socket;
import database.daos.PersoanaDao;
import database.models.PersoanaEntity;
import jakarta.persistence.NoResultException;
import org.json.JSONObject;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.Optional;
public class ProcessInput {
void processInput(JSONObject data, ObjectOutputStream out) {
switch (data.get("type").toString())
{
case "LOGIN_USER":
PersoanaDao persoanaDao = new PersoanaDao();
String username = data.get("username").toString();
JSONObject json = new JSONObject();
try {
PersoanaEntity persoanaEntity = persoanaDao.get(username);
json.put("status_code", "200");
} catch(Exception e) {
json.put("status_code", "404");
}
try {
out.writeObject(json.toString());
} catch (IOException e)
{
System.out.println(e.toString());
}
break;
}
}
}
I won't add the code from the client side because I'm quite sure the problem is from the server after doing some tests. I think that it happens because the run method is only called once, AFAIK, and that is when .start() is called from the Thread.
Then it won't ever be called again so there will never be data in the received string.
Am I right?
If so, what's the fix?
If not, why am I getting data only once and how can I fix it?
//edit: I will add the client just in case:
package socket;
import org.json.JSONObject;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Scanner;
public enum Client implements Runnable {
INSTANCE;
public static final int PORT = 27015;
public Socket getSocket() {
return socket;
}
public ObjectInputStream getInputStream() {
return inputStream;
}
public ObjectOutputStream getOutputStream() {
return outputStream;
}
private Socket socket = null;
private ObjectInputStream inputStream = null;
private ObjectOutputStream outputStream = null;
private String name;
Client() {
try {
socket = new Socket("localhost", PORT);
this.outputStream = new ObjectOutputStream(socket.getOutputStream());
this.inputStream = new ObjectInputStream(socket.getInputStream());
} catch(Exception e) {
System.out.println("Connection error");
}
}
public void run() {
System.out.println("Client socket running");
//For receiving data
boolean isClose = false;
while (!isClose) {
}
try {
socket.close();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
I have a java server with multiple clients connections. If one client sends a message to the server v the server broadcasts the message to all clients. What should I change in the code so that it answers only the client who sent the message?
Hereby the code:
EchoServer.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class EchoServer
{
public static void main(String[] args) throws IOException
{
EchoServer server = new EchoServer();
server.start();
}
private ArrayList<PrintWriter> writers = new ArrayList<>();
public void start() {
ServerSocket serverSocket = null;
try
{
serverSocket = new ServerSocket(5000);
while (true) {
Socket clientSocket = serverSocket.accept();
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
writers.add(out);
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
Thread t = new ClientHandler(in, this);
t.start();
}
}
catch (IOException e)
{
System.out.println("Exception caught when trying to listen on port 5000 or listening for a connection");
System.out.println(e.getMessage());
}
finally
{
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public synchronized void broadcast(String inputLine) {
for (PrintWriter writer : writers) {
writer.println(inputLine);
}
}
}
EchoClient.java
import java.io.*;
import java.net.*;
public class EchoClient
{
public static void main(String[] args) throws IOException
{
String hostName = "localhost";
int portNumber = 5000;
Socket echoSocket = null;
try
{
echoSocket = new Socket(hostName, portNumber);
PrintWriter out = new PrintWriter(echoSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
Thread t = new ServerHandler(in);
t.start();
String userInput;
while ((userInput = stdIn.readLine()) != null)
{
out.println(userInput);
}
}
catch (UnknownHostException e)
{
System.err.println("Don't know about host " + hostName);
System.exit(1);
}
catch (IOException e)
{
System.err.println("Couldn't get I/O for the connection to " + hostName);
System.exit(1);
}
finally
{
echoSocket.close();
}
}
}
ServerHandler
import java.io.BufferedReader;
import java.io.IOException;
public class ServerHandler extends Thread {
private BufferedReader reader;
public ServerHandler(BufferedReader reader) {
super();
this.reader = reader;
}
#Override
public void run() {
String readLine;
try {
while((readLine = reader.readLine()) != null) {
System.out.println(readLine);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
ClientHandler
import java.io.BufferedReader;
import java.io.IOException;
public class ClientHandler extends Thread {
private BufferedReader reader;
private EchoServer server;
public ClientHandler(BufferedReader reader, EchoServer server)
{
this.reader = reader;
this.server = server;
}
#Override
public void run() {
while (true) {
String inputLine;
try {
while ((inputLine = reader.readLine()) != null)
{
server.broadcast(inputLine);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Currently, when you receive a message from a client, your ClientHandler calls the server's broadcast method. Here is how I would only echo to one client.
1) Pass the clientSocket into the ClientHandler. So the code below would replace the code in the EchoServer.
Thread t = new ClientHandler(in, clientSocket, this);
t.start();
Then your client handler would have a socket, that it could write back too.
import java.io.BufferedReader;
import java.io.IOException;
import java.net.Socket;
public class ClientHandler extends Thread {
private BufferedReader reader;
private Socket clientSocket;
private EchoServer server;
public ClientHandler(BufferedReader reader, Socket clientSocket EchoServer server)
{
this.reader = reader;
this.server = server;
this.clientSocket = clientSocket;
}
#Override
public void run() {
while (true) {
String inputLine;
try {
while ((inputLine = reader.readLine()) != null)
{
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
out.println(inputLine);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
I'm newbie on the network programming. I want to make an simple server/client program in order to understand the basics of sockets. But unfortunately I can't understand one concept. Can I call readUTF() method before before client sends message? Because when I call second time this method my program crashes.
Error:
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at java.io.DataInputStream.readUnsignedShort(Unknown Source)
at java.io.DataInputStream.readUTF(Unknown Source)
at java.io.DataInputStream.readUTF(Unknown Source)
at Messaging.ServerSideConnection.receiveData(ServerSideConnection.java:59)
at Messaging.Server.printInputs(Server.java:88)
at Messaging.Server$2.run(Server.java:35)
at java.lang.Thread.run(Unknown Source)
Server:
package Messaging;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class Server {
private static final String configId = "SERVER_CONFİG_ID_";
private static final int port = 6066;
private volatile ArrayList<ServerSideConnection> connections;
public static void main(String[] args){
new Server();
}
public Server(){
connections = new ArrayList<>();
Thread acceptConnections = new Thread(new Runnable(){
public void run() {
try {
acceptConnections(port);
} catch (IOException e) {
e.printStackTrace();
}
}
});
Thread printInputs = new Thread(new Runnable(){
public void run() {
while(true){
printInputs();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
acceptConnections.start();
printInputs.start();
try {
acceptConnections.join();
printInputs.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void acceptConnections(int port) throws IOException{
ServerSocket serverSocket = new ServerSocket(port);
while(true){
System.out.println("SERVER : Listening..");
ServerSideConnection connection = new ServerSideConnection(serverSocket.accept());
connection.sendData(configId + Integer.toString(connection.getId()));
connections.add(connection);
System.out.println("SERVER : Connected to " + connection.getSocket().getInetAddress());
}
}
public void controlConnectionLife(){
int instantSize = connections.size();
for(int i=0;i<instantSize;i++){
if(!connections.get(i).isConnected()){
connections.get(i).killConnection();
connections.remove(i);
i--;
}
}
}
public void printInputs(){
for (ServerSideConnection connection : connections){
System.out.println(connection.isConnected());
try {
System.out.println(connection.receiveData());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
public class ServerSideConnection {
private static int count;
private int id;
private Socket socket;
private DataInputStream input;
private DataOutputStream output;
public ServerSideConnection(Socket socket){
this.socket = socket;
initOutputStream();
initInputStream();
count++;
id = count;
}
private void initInputStream(){
try {
InputStream in = socket.getInputStream();
input = new DataInputStream(in);
} catch (IOException e) {
e.printStackTrace();
}
}
private void initOutputStream(){
try {
output = new DataOutputStream(socket.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
public void killConnection(){
try {
output.close();
input.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public String receiveData() throws IOException{
return input.readUTF();
}
public void sendData(String msg) throws IOException{
output.writeUTF(msg);
output.flush();
}
public boolean isConnected(){
return socket.isConnected();
}
public int getId(){
return id;
}
public Socket getSocket(){
return socket;
}
public DataInputStream getInput() {
return input;
}
public DataOutputStream getOutput() {
return output;
}
}
Client:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ConnectException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
public class ClientSideConnection {
private static final String configId = "SERVER_CONFİG_ID_";
private static final int port = 6066;
private static final String host = "localhost";
private int id;
private Socket socket;
private DataInputStream input;
private DataOutputStream output;
public static void main(String[] args){
try {
new ClientSideConnection(port,host);
} catch (IOException e) {
e.printStackTrace();
}
}
public ClientSideConnection(int port, String host) throws UnknownHostException, IOException{
boolean connected = false;
while(!connected){
try{
socket = new Socket(host,port);
connected = true;
System.out.println("CLIENT : Connected to " + socket.getInetAddress());
}
catch(ConnectException e){
connected = false;
}
}
initOutputStream();
initInputStream();
String receivedId = receiveData();
if(receivedId.substring(0, 17).equals(configId))
id = Integer.parseInt(receivedId.substring(17,receivedId.length()));
sendTestData();
}
private void initInputStream(){
try {
input = new DataInputStream(socket.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
private void initOutputStream(){
try {
output = new DataOutputStream(socket.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
public void killConnection(){
try {
output.close();
input.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public String receiveData() throws IOException{
return input.readUTF();
}
public void sendData(String msg) throws IOException{
output.writeUTF(msg);
output.flush();
}
public int getId() {
return id;
}
public void sendTestData(){
Scanner scan = new Scanner(System.in);
System.out.print("enter test msg: ");
String msg = scan.nextLine();
try {
sendData(msg);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("msg sended!");
}
}
As the exception message states, the second call to readUTF is failing because the connection is being closed by the client. The code running the client currently follows the sequence of:
Establish connection
Setup input and output streams
Read data from server
Send data to server
After sending data to the server, there is no code left and no loop to repeat the process of sending/receiving, so the client closes its end of the connection and exits. You'll need to add a 5th step to your sequence:
Establish connection
Setup input and output streams
Read data from server
Send data to server
Jump to 3 until a stopping condition is met
One approach to this sequence could be:
public class Client {
public static void main(String[] args) {
Client client = new Client();
boolean sucessful;
do {
String data = client.receiveData();
successful = client.sendData(data);
} while(successful);
client.close();
}
public Client() {
//setup connection and in/output streams
}
public String receiveData() {
//read from input
}
public boolean sendData(String data) {
//send data
}
public void close() {
}
}
for an exam i have to make a synchronous multiplayergame, to practice with the serverside, i decided to make a little sketch in processing where two clients exchange the mouse's positions.
The idea is when two client are connected to the server, the server spawn a thread with the two connections, in the thread client send his data to server and server turn the data to the client, so the server is a simple bridge for the clients.
This is the Java server code:
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ProvaServerGioco {
public final static int PORT = 31946;
public final static int MAXPARTITE = 50;
private Socket player1;
private Socket player2;
public final static char separatore = '\n';
public static final String INDIRIZZOHAMACHI = "25.166.111.50";
public static final String INDIRIZZOLAN = "192.168.1.65";
public void start() throws UnknownHostException {
ExecutorService pool = Executors.newFixedThreadPool(MAXPARTITE);
StringBuilder mouse=new StringBuilder();
InetAddress addr = InetAddress.getByName(INDIRIZZOHAMACHI);
try (ServerSocket server = new ServerSocket(PORT, 0, addr)) {
while (true) {
{
if (player1 == null) {
try {
player1 = server.accept();
System.out.println("Ryu");
Writer out = new OutputStreamWriter(
player1.getOutputStream());
out.write("in attesa di giocatore 2" + separatore);
out.flush();
} catch (IOException ex) {
player1.close();
player1 = null;
}
}
if (player2 == null) {
try {
player2 = server.accept();
System.out.println("Ken");
Writer out = new OutputStreamWriter(
player2.getOutputStream());
out.write("in attesa di giocatore 2" + separatore);
out.flush();
} catch (IOException ex) {
player2.close();
player2 = null;
}
}
if(!checkConnessione(player1))
player1=null;
if(!checkConnessione(player2))
player2=null;
if (player2 != null && player1 != null) {
pool.submit(new ThreadPartita(player1, player2));
player1 = null;
player2 = null;
}
}
}
} catch (IOException ex) {
System.err.println(ex);
}
}
private boolean checkConnessione(Socket player) {
if (player != null)
try {
Writer out = new OutputStreamWriter(player.getOutputStream());
out.write(separatore);
out.flush();
return true;
} catch (IOException ex) {
try {
player.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
return false;
}
public static void main(String[] args) {
ProvaServerGioco server = new ProvaServerGioco();
try {
server.start();
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
And this is the thread for the match:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.Socket;
import java.util.concurrent.Callable;
public class ThreadPartita implements Callable<Void>{
private Socket player1;
private Socket player2;
private Writer player1Out;
private Writer player2Out;
private BufferedReader readerPlayer1;
private BufferedReader readerPlayer2;
private boolean finePartita=false;
public ThreadPartita(Socket player1,Socket player2)
{
this.player1=player1;
this.player2=player2;
}
#Override
public Void call() throws Exception {
notificaConnessione(player1);
notificaConnessione(player2);
player1Out=new OutputStreamWriter(
player1.getOutputStream());
player2Out=new OutputStreamWriter(
player2.getOutputStream());
readerPlayer1=new BufferedReader(new InputStreamReader(player1.getInputStream(), "ASCII"));
readerPlayer2=new BufferedReader(new InputStreamReader(player2.getInputStream(), "ASCII"));
String mousePlayer1="";
String mousePlayer2="";
while(true&&!finePartita)
{
mousePlayer2=readerPlayer2.readLine();
mousePlayer1=readerPlayer1.readLine();
player1Out.write(mousePlayer2+ProvaServerGioco.separatore);
player1Out.flush();
System.out.println(mousePlayer1);
System.out.println(readerPlayer2.ready());
player2Out.write(mousePlayer1+ProvaServerGioco.separatore);
player2Out.flush();
}
return null;
}
private void inviaMessaggio(Socket player,String messaggio)
{
try{
Writer out = new OutputStreamWriter(
player.getOutputStream());
out.write(messaggio);
out.flush();
}
catch(IOException ex)
{
System.out.println("partita annullata");
}
}
private void notificaConnessione(Socket player)
{
inviaMessaggio(player,"Sei connesso"+ProvaServerGioco.separatore);
}
}
The problem in this code is when i read the data from the player2 in ThreadPartita:
mousePlayer2=readerPlayer2.readLine();
In this line the program freezes, if i comment that line everything is working and player1 send his data to player2 correctly.
I know for sure that is a noob error, but i don't know how to fix it cause i'm a beginner with server socket (i'am studyng the book "java network programming" from o'Reilly in this days).
I don't know if can be useful, but this is the code in processing for the clientside:
import java.net.*;
import java.io.*;
import java.io.Writer;
StringBuilder mouse;
final static int PORTA=31946;
//final static int PORTA=13;
String mouseStringa;
String hamachiIP="127.0.0.1";
Socket socket;
Writer out;
BufferedReader reader;
void setup()
{
size(800,800);
try{
socket = new Socket(hamachiIP, PORTA);
socket.setSoTimeout(15000);
out=new OutputStreamWriter(
socket.getOutputStream());
InputStream in = socket.getInputStream();
mouse = new StringBuilder();
reader = new BufferedReader(new InputStreamReader(in, "ASCII"));
mouseStringa=reader.readLine();
}
catch (IOException ex)
{
System.err.println(ex);
}
}
void draw()
{
background(255);
println(mouseStringa);
try{
mouse = new StringBuilder();
if(reader.ready())
{
String appoggio=reader.readLine();
if(appoggio.length()>0)
mouseStringa=reader.readLine();
}
String posizioniMouse=""+mouseX+';'+mouseY+'\n';
out.write(posizioniMouse);
out.flush();
}
catch (IOException ex)
{
System.err.println(ex);
}
frame.setTitle("fps: "+frameRate);
}
Thank you for your attention!