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.
Related
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.
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();
}
}
I am trying to run the code in a windows comman line and received exception :
D:\dasi\java\javaLab>java ServerClient
java.net.ConnectException: Connection refused: connect
java.lang.StringIndexOutOfBoundsException: String index out of range: -2
D:\dasi\java\javaLab>
in another command line windw :
D:\dasi\java\javaLab>java SocketClient
java.net.ConnectException: Connection timed out: connect
D:\dasi\java\javaLab>
Server code :
import java.io.*;
import java.net.*;
public class ServerClient {
public ServerClient(int port) {
Server server = new Server(port);
server.start();
Client client = new Client(port);
client.start();
}
public static void main(String[] args) {
ServerClient s1 = new ServerClient(7777);
}
}
class Server extends Thread {
int port;
ServerSocket server;
Socket socket;
DataOutputStream outStream = null;
DataInputStream inStream = null;
public Server(int poort) {
try {
this.port = port;
server = new ServerSocket(port);
}
catch(Exception e) {
System.out.println(e.toString());
}
}
public void run() {
try {
socket = server.accept();
outStream = new DataOutputStream(socket.getOutputStream());
inStream = new DataInputStream(socket.getInputStream());
System.out.println("server is ok, please continue!");
while(true) {
String str = inStream.readUTF();
System.out.println("The server receive String:"+str);
outStream.writeUTF(str);
}
}
catch(Exception e) {
System.out.println(e.toString());
}
}
}
class Client extends Thread {
int port;
Socket socket;
DataInputStream inStream = null;
DataOutputStream outStream = null;
public Client(int port) {
try {
this.port = port;
socket = new Socket(InetAddress.getLocalHost(),port);
inStream = new DataInputStream(socket.getInputStream());
outStream = new DataOutputStream(socket.getOutputStream());
System.out.println("client is ok, please continue!");
}
catch(Exception e) {
System.out.println(e.toString());
}
}
public void run() {
try {
while(true) {
byte[] b = new byte[1024];
String str = "";
int m = System.in.read(b);
str = new String(b,0,0,m-1);
outStream.writeUTF(str);
str = inStream.readUTF();
System.out.println("The client receive String:"+str);
}
}
catch(Exception e) {
System.out.println(e.toString());
}
}
}
Client code :
import java.net.*;
import java.io.*;
public class SocketClient {
Socket s = null;
DataInputStream inStream = null;
DataOutputStream outStream = null;
public SocketClient() {
try {
init();
waitData();
}
catch(Exception e) {
System.out.println(e.toString());
}
}
void init() throws Exception {
s=new Socket("10.15.43.216",8765);
inStream = new DataInputStream(s.getInputStream());
outStream = new DataOutputStream(s.getOutputStream());
s.setSoTimeout(3000);
}
void waitData() {
while(true) {
try {
String str = inStream.readUTF();
System.out.println("Client accept:" +str);
str = Integer.toString(Integer.parseInt(str)+1);
outStream.writeUTF(str);
}
catch(Exception e) {
System.out.println(e.toString());
break;
}
}
}
public static void main(String[] args) {
new SocketClient();
}
}
I am wodering if there's anything wrong in my code or if it was my computer port that cause the problem. Because when I checked my computer port I didn't see 7777. When I issued command netstat -nao | findstr 7777, it returned nothing.
D:\dasi\java\javaLab>netstat -nao | findstr 7777
D:\dasi\java\javaLab>
If it was the port problem, then how to open the 7777 port.
I am a newbie here, please help. Thanks a lot!
replace
public Server(int poort) {
try {
this.port = port;
...
}
}
with
public Server(int poort) {
try {
this.port = port;
...
}
}
or rather the default value of port is zero, then your serverSocket will bind with 0 port rather than 7777.
and as for this code segment:
public ServerClient(int port) {
Server server = new Server(port);
server.start();
Client client = new Client(port);
client.start();
}
I am afraid it is easy to make you in trouble, because we cant ensure the server thread will execute before client thread and if client thread execute first when server havent run it will cause error. And you already have a client in another java file, so I cant understand why you have an Client here. Maybe you could remove them, the code can be this:
public ServerClient(int port) {
Server server = new Server(port);
server.start();
}
as for Client Code
your server socket is 7777 so you should connect 7777 port rather than 8765 in you init method maybe the code can be this:
void init() throws Exception {
s=new Socket(server name,7777);
...
}
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.
I'm trying to create a java push server model for testing on my own machine, this won't be used to connect external clients as the server and client will be on the same machine. After the client connects on the port specified by he/she, they should send a message of their choice that will be sent back to them, and any other clients connected to the same port.
The problem I'm having is i receive a java.net.ConnectException: Connection refused: connect when this is attempted. Below is the client and the server.
Edit: I've taken the time to ensure that the necessary ports are open too, and even disabled my firewall, but to no avail.
Server:
class MainServer {
// port that oir server is going to operate on
final static int port = 1234;
public static void main(String[] args) {
// this is going to model the server for the moment
System.out.println("Server has been started...");
Buffer<Messages> store = new Buffer<Messages>(10);
new Writer(store).start();
try {
ServerSocket serve = new ServerSocket(port);
while(true) {
// wait for server request
Socket socket = serve.accept();
// start thread to service request
new ServerThread(socket,store).start();
}
} catch(IOException e) {e.printStackTrace();}
}
}
class ServerThread extends Thread {
Socket socket;
Buffer<Messages> buffer;
public ServerThread(Socket s, Buffer<Messages> b) {
socket = s;buffer = b;
}
public void run() {
try {
DataInputStream in = new DataInputStream(socket.getInputStream());
int port = in.readInt();
System.out.println("Port: "+port);
Messages ms = new Messages(port);
// Read message as string from user
String message = in.readUTF();
int k = in.readInt();
while(k != -1) {
// Add message to array
// read next message
ms.add(message);
message = in.readUTF();
}
// close connection
socket.close();
// add message to buffer
buffer.put(ms);
} catch(IOException e) {e.printStackTrace();}
}
}
class Writer extends Thread {
Buffer<Messages> buffer;
public Writer(Buffer<Messages> m) {buffer = m;}
public void run() {
while(true) {
Messages dp = buffer.get();
dp.write();
}
}
}
class Buffer <E> {
/**
* Producer & Consumer Buffer
*/
private int max;
private int size = 0;
private ArrayList<E> buffer;
private Semaphore empty; //control consumer
private Semaphore full; // control producer
private Lock lock = new ReentrantLock();
public Buffer(int s) {
buffer = new ArrayList<E>();
max = s;
empty = new Semaphore(0);
full = new Semaphore(max);
}
// add data to our array
public void put(E x) {
try {
full.acquire();
} catch(InterruptedException e) {}
// sync update to buffer
lock.lock();
try {
buffer.add(x);
size++;
empty.release();
} finally {lock.unlock();}
}
public E get() {
try {
empty.acquire();
} catch(InterruptedException e) {}
// sync uodate on buffer
lock.lock();
try {
E temp = buffer.get(0);
buffer.remove(0);
size--;
full.release();
return temp;
} finally {lock.unlock();}
}
}
final class Messages {
private final int port;
private final ArrayList<String> data = new ArrayList<String>();
public Messages(int p) {port = p;}
void add(String message) {
data.add(message);
}
void write() {
try {
Socket socket;
socket = new Socket(InetAddress.getLocalHost(),port);
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
// write message
out.write(data.size());
for(String k : data) {out.writeUTF(k);}
out.flush();
socket.close();
} catch(IOException e) {e.printStackTrace();}
}
}
Client:
class Client {
final static int nPort = 1234;
static int serverPort;
public static void main(String[] args) {
// this class and those present in it
// will model the client for assignment 8
Scanner in = new Scanner(System.in);
System.out.println("Please enter the messageboard number: ");
serverPort = in.nextInt();
System.out.println("Please type your message: ");
String msg = in.next();
Listener lis = new Listener(serverPort);
lis.start();
boolean go = true;
while(go) {
try {
Thread.sleep(2000);
} catch(InterruptedException e) {}
write(serverPort, msg);
System.out.println("Continue: 0/1");
int x = in.nextInt();
if(x == 0)go = false;
}
System.exit(0);
}
static void write(int port, String msg) {
try {
Socket socket;
socket = new Socket(InetAddress.getLocalHost(),port);
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
// send message to port
out.writeInt(port);
out.writeUTF(msg);
// write sentinal after message has been written and close socket
out.writeInt(-1);
out.flush();
socket.close();
} catch(IOException e) {System.out.println(e);}
}
}
class Listener extends Thread {
private int port;
volatile boolean go;
public Listener(int p) {p = port;}
public void run() {
try {
ServerSocket serversock = new ServerSocket(port);
while(go) {
Socket socket = serversock.accept();
DataInputStream in = new DataInputStream(socket.getInputStream());
// Read the message
while(in.available() > 0) {
String k = in.readUTF();
System.out.print(k+" ");
}
System.out.println();
socket.close();
}
} catch(IOException e) {go = false;}
}
}
Turns out i had a wrong assignment in my Listener class. I had p = port instead of port = p.
Solved. Through my own stupidity.
The hostname you are connecting to is localhost so you are assuming the server is on the same machine. If you need to connect to a different machine, you need to specify the host you want it to connect to.
Try changing socket = new Socket(InetAddress.getLocalHost(),port);
to
socket = new Socket(*IP OF SERVER (127.0.0.1 if same machine)*, port);