How to fix "no communication between server and client" - java

This is code provided to me for a class. I am trying trying to fix a connection problem between the client and server. Even when both are started they do not connect.
This is for a Java based game of Battleship that will allow two users on separate devices to play one another. I'm not sure why the two do not connect and even the debugger has not been much help in directing me to the problem.
public class GameClient
{
private Socket clientSocket;
private PrintWriter out;
private BufferedReader in;
public void openConnection(String ip, int port)
{
try
{
clientSocket = new Socket(ip, port);
out = new PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
}
catch (Exception e)
{
System.out.println("Error opening client socket");
}
}
public String sendMessage(String msg)
{
String resp = "";
try
{
out.println(msg);
resp = in.readLine();
}
catch (Exception e)
{
System.out.println("Error sending message from Client");
}
return resp;
}
public void stop()
{
try
{
in.close();
out.close();
clientSocket.close();
}
catch (Exception e)
{
System.out.println("Error stopping client");
}
}
public static void main(String[] args)
{
GameClient client = new GameClient();
client.openConnection("10.7.232.200", 3333);
String response = client.sendMessage("1,2");
System.out.println(response);
client.stop();
}
}
public class GameServer
{
private ServerSocket serverSocket;
private Socket clientSocket;
private PrintWriter out;
private BufferedReader in;
public void start(int port)
{
try
{
serverSocket = new ServerSocket(port);
clientSocket = serverSocket.accept();
out = new PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String move = in.readLine();
System.out.println(move);
out.println("6,1");
}
catch (Exception e)
{
System.out.println("Socket opening error");
}
}
public void stop()
{
try
{
in.close();
out.close();
clientSocket.close();
serverSocket.close();
}
catch (Exception e)
{
System.out.println("Error closing sockets");
}
}
public static void main(String [] args)
{
GameServer server = new GameServer();
server.start(3333);
server.stop();
}
}
public class PlayBattleship
{
public static void main(String[] args)
{
GameClient client = new GameClient();
client.openConnection("10.7.232.200", 3333);
//System.out.println(response);
BattleshipGame game = new BattleshipGame();
while (!game.checkEndgame())
{
game.getGuess(client);
}
client.stop();
}
}
The client and server should connect and stay connected till the game has reached completion
EDIT: I have thoroughly read the API documentation but still cannot understand the problem.

The Server in your code isn't waiting for the incoming requests, it only serves a single incoming request and then kills itself due to the nature of the main method which starts it.
You need to have the server wait for the requests and do not die. Check the code snippet below to understand the logic.
Plus, always try to throw the exceptions if you can't do anything meaningful with it within the method it is caught in. In your code the main method of the server will anyway execute even if there is an exception caught in the start method
public class GameServer {
private ServerSocket serverSocket;
private Socket clientSocket;
private PrintWriter out;
private BufferedReader in;
public ServerSocket start(int port) throws IOException {
serverSocket = new ServerSocket(port);
return serverSocket;
}
public void stop() throws IOException {
in.close();
out.close();
clientSocket.close();
serverSocket.close();
}
// This method accepts and serves the incoming requests
public void acceptConnection(ServerSocket serverSocket) throws IOException {
clientSocket = serverSocket.accept();
out = new PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String move = in.readLine();
System.out.println(move);
out.println("6,1");
}
public static void main(String[] args) throws IOException {
GameServer server = new GameServer();
ServerSocket serverSocket = server.start(3333);
System.out.println("Server Started");
// The effective change you need to make
// Loop through the incoming requests
while(true) {
server.acceptConnection(serverSocket);
}
}
}
public class GameClient {
private Socket clientSocket;
private PrintWriter out;
private BufferedReader in;
public void openConnection(String ip, int port) throws IOException {
clientSocket = new Socket(ip, port);
out = new PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
}
public String sendMessage(String msg) throws IOException {
String resp = "";
out.println(msg);
resp = in.readLine();
return resp;
}
public void stop() throws IOException {
in.close();
out.close();
clientSocket.close();
}
public static void main(String[] args) throws IOException {
GameClient client = new GameClient();
client.openConnection("10.7.232.200", 3333);
String response = client.sendMessage("1,2");
System.out.println(response);
client.stop();
}
}

Related

Java - establish a chat between two clients

Im trying to code a simple server that creates a chat between any two clients that connect to the server. (for any two new clients the server will open a new chat thred/s and then will wait to the next two clients)
i have tried the followןng solution:
Server:
public class Server
{
public Server() throws IOException
{
ServerSocket sc = new ServerSocket(7777);
Socket s1, s2;
while(true)
{
s1 = sc.accept();
s2 = sc.accept();
new ServerThread(s1, s2).start();
new ServerThread(s2, s1).start();
}
}
}
Server threads (two threads as explained in the comment above the class)
/*
Receives message from sender socket and pass them to the recipient socket
*/
public class ServerThread extends Thread
{
Socket sender;
Socket recipient;
public ServerThread(Socket sender, Socket recipient)
{
this.sender = sender;
this.recipient = recipient;
}
#Override
public void run()
{
try {
handle();
} catch (IOException e) {
e.printStackTrace();
}
}
public void handle() throws IOException
{
String msg;
// Create output stream for the recipient
OutputStream outputStream = recipient.getOutputStream();
ObjectOutputStream objOutputStream = new ObjectOutputStream(outputStream);
// Create input stream for the recipient
InputStream inputStream = sender.getInputStream();
ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
while(true) //sender.isConnected())
{
msg = objectInputStream.readUTF();
if(true) //recipient.isConnected())
objOutputStream.writeUTF(msg);
else
break;
}
sender.close();
recipient.close();
}
}
(Please note that i removed the condotion in the "while" and "if" since i wanted to eliminate anything that will might appear because of it)
Clients main:
public class ClientMain
{
public static void main(String[] args)
{
String s;
Scanner scan = new Scanner(System.in);
try {
ClientChat chat = new ClientChat("localhost", 7777);
//while true gets messages if any and print them to the console
chat.getMessages();
s = scan.nextLine();
while(!s.equals("1"))
{
chat.sendMessage(s);
s = scan.nextLine();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Clients Thread:
public class ClientChat
{
Socket socket;
String ip;
int port;
OutputStream outputStream;
ObjectOutputStream objOutputStream;
InputStream inputStream;
ObjectInputStream objectInputStream;
public ClientChat(String ip, int port) throws UnknownHostException, IOException
{
this.ip = ip;
this.port = port;
socket = new Socket(ip, port);
// Create output stream for the recipient
outputStream = socket.getOutputStream();
objOutputStream = new ObjectOutputStream(outputStream);
// Create input stream for the recipient
inputStream = socket.getInputStream();
objectInputStream = new ObjectInputStream(inputStream);
}
public void getMessages() throws IOException
{
Thread t = new Thread(new Runnable() {
#Override
public void run() {
while(true)//socket.isConnected())
{
String msg;
try {
msg = objectInputStream.readUTF();
System.out.println(msg);
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
t.start();
}
public void sendMessage(String message)
{
try {
objOutputStream.writeUTF(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Well, this code doesn't work,
I have run the server and two clients, the clients do connect to the server, and you can
enter input to readLine() method, but nothing happen.
i have tried to dubug the server, what i found is that it stack on the line:
msg = objectInputStream.readUTF();
that all the relevant info i have, if you need some more information please comment
You need to call the flush() method from the ObjectOutputStream object. If you don't the data to send are stored in an internal buffer. It will get only send when the buffer is full or when you explicit call the flush() method.

java.net.SocketException: Software caused connection abort: socket write error when resubmitting the request

working with sockets on this problem. I wrote the implementation of Http and TCP servers. HTTP works completely correctly, so I can send requests to the server one by one. What can not be said about the TCP server, the first request leaves and is handled correctly, but when you try to send the following request, throws this exception:
java.net.SocketException: Software caused connection abort: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:111)
at java.net.SocketOutputStream.write(SocketOutputStream.java:134)
at java.io.DataOutputStream.writeBytes(DataOutputStream.java:276)
at Main.main(Main.java:24)
After that, the client side is closed, and the server side continues to work.HTTP and TCP are implemented from the same Server class, which starts the server.
MyServer:
public abstract class Server implements Runnable {
private final Socket clientSocket;
public Server(Socket clientSocket) {
this.clientSocket = clientSocket;
}
#Override
public void run() {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
BufferedWriter output = new BufferedWriter(new PrintWriter(clientSocket.getOutputStream()))) {
String req = getRequest(reader);
setResponse(output, req);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Class that starts the server:
public class RunServer extends Thread {
private final int port;
private ExecutorService executorService;
private String serverType;
private ServerFactoryContainer serverFactoryContainer;
public RunServer(String serverType, int port) {
this.port = port;
this.executorService = Executors.newFixedThreadPool(4);
this.serverType = serverType;
this.serverFactoryContainer = new ServerFactoryContainer();
}
#Override
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(port);
while (!isInterrupted()) {
Socket clientSocket;
try {
clientSocket = serverSocket.accept();
executorService.execute(serverFactoryContainer.getServerFactory(serverType).createServer(clientSocket));
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
TCP client-side:
public class Main {
public static void main(String[] args) throws IOException {
String req;
String resp;
try (Socket clientSocket = new Socket(InetAddress.getLocalHost(), Constants.ServerConstant.TCP_PORT);
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(System.in));
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()))) {
while (true) {
System.out.println("Write command [get count] or [get item]");
req = inFromClient.readLine().toLowerCase();
outToServer.writeBytes(req + "\n"); // I get an exception here when I send a request to the server
resp = inFromServer.readLine();
if (!resp.isEmpty()) {
System.out.println(resp);
}
if (req.equals("exit")) {
System.exit(1);
}
}
}
}
Why do I get the exception that I indicated above when I resubmit the request to the TCP server and why is this exception not thrown when sending a second request to the HTTP server?
#Override
protected String getRequest(BufferedReader input) throws IOException {
return input.readLine();
}
#Override
protected void setResponse(BufferedWriter output, String request) throws IOException {
String result = serverCommandController.execute(RequestParser.tcpParserCommand(request));
output.write(result);
output.flush();
}
You are closing the client connection before the client is done. Try this in your Server class:
#Override
public void run()
{
try (BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); BufferedWriter output = new BufferedWriter(new PrintWriter(clientSocket.getOutputStream())))
{
while (clientSocket.isConnected())
{
String req = getRequest(reader);
setResponse(output, req);
}
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
try
{
clientSocket.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
Your server appears to close the socket after sending a response. After that, the client will not be able to send further requests without opening a new connection. Typically, the server allows the client to control the fate of the connection, so that the client can send multiple requests. Your client could send a "close" request to indicate to the server that the client intends to close the socket and does not expect a response.

Client-to-Client with server intermediary

I am trying to implement Client to Client which passes through the server. Client1 sends a line to the server and server forwards it to all the other clients.
Can you point out my mistake. Nothing is printed on the other clients.
Server Code:
public class Server {
int port;
ServerSocket server=null;
Socket socket=null;
ExecutorService exec = null;
ArrayList clients = new ArrayList();
DataOutputStream dos=null;
public static void main(String[] args) throws IOException {
Server serverobj=new Server(2000);
serverobj.startServer();
}
Server(int port){
this.port=port;
exec = Executors.newFixedThreadPool(3);
}
public void startServer() throws IOException {
server=new ServerSocket(2000);
System.out.println("Server running");
while(true){
socket=server.accept();
dos = new DataOutputStream(socket.getOutputStream());
clients.add(dos);
ServerThread runnable= new ServerThread(socket,new ArrayList<>(clients),this);
exec.execute(runnable);
}
}
private static class ServerThread implements Runnable {
Server server=null;
Socket socket=null;
BufferedReader brin;
Iterator it=null;
Scanner sc=new Scanner(System.in);
String str;
ServerThread(Socket socket, ArrayList clients ,Server server ) throws IOException {
this.socket=socket;
this.server=server;
System.out.println("Connection successful with "+socket);
brin=new BufferedReader(new InputStreamReader(socket.getInputStream()));
it = clients.iterator();
}
#Override
public void run() {
try{
while ((str = brin.readLine()) != null) {
while (it.hasNext()) {
try{
DataOutputStream dost=(DataOutputStream) it.next();
dost.writeChars(str);
dost.flush();
}
catch(IOException ex){
System.out.println("Error 1 "+ex);
}
}
}
brin.close();
socket.close();
}
catch(IOException ex){
System.out.println("Error 2 "+ex);
}
}
}
}
Client 1 code:
public class Client1 {
public static void main(String args[]) throws IOException{
String str;
Socket socket=new Socket("127.0.0.1",2000);
PrintStream prout=new PrintStream(socket.getOutputStream());
BufferedReader bread=new BufferedReader(new InputStreamReader(System.in));
BufferedReader dis=new BufferedReader(new InputStreamReader(socket.getInputStream()));
while(true){
System.out.println("Send to others:");
str=bread.readLine();
prout.println(str);
}
}
}
Other Clients:
public class Client2 {
public static void main(String args[]) throws IOException{
String str;
Socket socket=new Socket("127.0.0.1",2000);
BufferedReader dis=new BufferedReader(new InputStreamReader(socket.getInputStream()));
while(true){
str=dis.readLine();
System.out.print("Message: "+str+"\n");
}
}
}
Please help.. I have been at it for 2 days...

Simple chat client and chat server [duplicate]

This question already has an answer here:
ObjectInputStream(socket.getInputStream()); does not work
(1 answer)
Closed 7 years ago.
I'm doing a simple echo chat and server, but methods send and receive in class Connection don't work with ObjectInputStream and ObjectOutputStream, but with PrintWriter and BufferedReader work fine.
Now I'm trying to understand the serialization using sockets, help me to understand why this code does not work:
Client
public class Client {
private Connection connection;
private String getServerAddress() {
return "localhost";
}
private int getServerPort() {
return 4444;
}
public void run() {
BufferedReader bis = new BufferedReader(new InputStreamReader(System.in));
try {
connection = new Connection(new Socket(getServerAddress(), getServerPort()));
SocketThread socketThread = new SocketThread();
socketThread.setDaemon(true);
socketThread.start();
while (true) {
String text = bis.readLine();
if (text.equalsIgnoreCase("exit"))
break;
connection.send(text);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Client client = new Client();
client.run();
}
public class SocketThread extends Thread {
#Override
public void run() {
try {
while (true) {
String message = connection.receive();
System.out.println(message);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Connection
public class Connection implements Closeable {
private final Socket socket;
private final ObjectInputStream in;
private final ObjectOutputStream out;
public Connection(Socket socket) throws Exception {
this.socket = socket;
this.in = new ObjectInputStream(socket.getInputStream());
this.out = new ObjectOutputStream(socket.getOutputStream());
}
public void send(String message) throws Exception {
out.writeObject(message);
}
public String receive() throws Exception {
return (String) in.readObject();
}
#Override
public void close() throws IOException {
in.close();
out.close();
socket.close();
}
}
Server
public class Server {
public static void main(String[] args) {
int port = 4444;
try (ServerSocket serverSocket = new ServerSocket(port)) {
while (true) {
Socket socket = serverSocket.accept();
new Handler(socket).start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static class Handler extends Thread {
private Socket socket;
public Handler(Socket socket) {
this.socket = socket;
}
#Override
public void run() {
try (Connection connection = new Connection(socket)) {
while (true) {
String message = connection.receive();
if (message.equals("exit"))
break;
System.out.println(message);
connection.send("Echo: " + message);
}
} catch (Exception e) {
}
}
}
}
This is because ObjectInputStream blocks trying to read the stream header written by an ObjectOutputStream in its constructor, and you are creating both of your input streams before the output streams. You can solve this by switching the order that you create the object streams in:
this.out = new ObjectOutputStream(socket.getOutputStream());
this.in = new ObjectInputStream(socket.getInputStream());
The javadoc for the ObjectOutputStream constructor also notes that you might want to flush the stream after creating it to ensure the header is sent.

Pushing changes from one client to all other connected clients through server?

So I have a client:
public class TalkClient extends Thread
{
private int port;
private String host;
DocCntl theDocCntl;
public TalkClient(String host, int port) throws IOException
{
this.host = host;
this.port = port;
theDocCntl = new DocCntl(this);
}
public void run()
{
try
{
System.out.println("Seeking connection...");
Socket socket = new Socket(host, port);
DataInputStream in = new DataInputStream(socket.getInputStream());
BufferedReader console = new BufferedReader(new InputStreamReader(System.in));
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
}catch(IOException e)
{
e.printStackTrace();
}
}
public static void main(String [] args)
{
int port = 5050;
try
{
Thread t = new TalkClient("127.0.0.1", port);
t.start();
}catch(IOException e)
{
e.printStackTrace();
}
}
public void pushToServer(){
String theData = this.theDocCntl.theDoc.docTA.getText();
}
}
And I have a server:
public class TalkServer extends Thread
{
private ServerSocket serverSocket;
public static DocCntl theCntl;
public TalkServer(int port) throws IOException
{
serverSocket = new ServerSocket(port);
}
public void run()
{
try
{
System.out.println("Listening for connections...");
Socket client = serverSocket.accept();
DataInputStream in = new DataInputStream(client.getInputStream());
BufferedReader console = new BufferedReader(new InputStreamReader(System.in));
DataOutputStream out = new DataOutputStream(client.getOutputStream());
}catch(IOException e)
{
e.printStackTrace();
}
}
public static void main(String [] args)
{
int port = 5050;
try
{
Thread t = new TalkServer(port);
t.start();
}catch(IOException e)
{
e.printStackTrace();
}
}
}
In the client, I have a method called pushToServer, which I want to take the String data from a textArea on the client, and then push that to all the other connected clients. But I'm not sure how to handle sending the message to each individual connected client through the sockets. I've given it some thought, and I think I need to do 3 things:
1) Create and maintain a list of connected clients(threads). In the server class itself? Or in another class?
2) On the server, have some means of 'catching' the String data from one client, and then pushing it to all the other clients. This is why(I think) I need the list of clients. If I can figure out how to catch this(maybe through the input stream?) and then iterate through the list of clients to their text areas.
3) On the client side, I need to be able to catch the string from the server.
Any help on these 3 things would be greatly appreciated.

Categories

Resources