Multithread Server and Client with sockets in Java - java

I am trying to create for a university project a server / slave / client project.
The server should open 2 ports, one port will be for the connection of the slave and another port for the client.
I have setup 2 threads 1 for the client and another for the slave. The client should sent random numbers to server and server should forward randomly those numbers to slave instances. The slave should check if the current number exist on their list and if it's not available to store it, otherwise they should sent a message to server that the number already exist.
Then I created the client thread which consist of 2 threads, one for sending the numbers to server and another thread to read messages coming from the server.
There is something wrong with the code of the PrintWriter, I cannot make it to send the numbers to server when the code is inside the thread. If I move the code on the main and cancel the thread the messages are being sent without any issue.
What could be the issue for this?
Below is the current code from server (master) and the client.
public class Client {
private static final int NUMBERS = 50;
private static final int AMPLITUDE = 100;
private static int masterPort;
public Client(int port) {
this.masterPort = port;
}
public static void main(String[] args) throws IOException{
String serverHostname = "127.0.0.1";
System.out.println("Αναμονή για σύνδεση στον σέρβερ " + serverHostname + " στην πόρτα 30091.");
Socket echoSocket = null;
BufferedReader in = null;
try {
echoSocket = new Socket(serverHostname, 18889);
in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Δεν μπορεί να πραγματοποιηθεί σύνδεση με τον σέρβερ: " + serverHostname);
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to: " + serverHostname);
System.exit(1);
}
ClientOut clientOut = new ClientOut(echoSocket);
clientOut.start();
ClientIn clientIn = new ClientIn(in);
clientIn.start();
in.close();
echoSocket.close();
}
public static class ClientOut extends Thread {
private PrintWriter out;
public ClientOut(Socket echoSocket) throws IOException {
this.out = new PrintWriter(echoSocket.getOutputStream(), true);
}
#Override
public void run() {
System.out.println("Ο client συνδέθηκε!");
Random rnd = new Random();
try {
for (int i=0; i<NUMBERS; i++) {
int num = rnd.nextInt(AMPLITUDE);
System.out.println(num);
out.println(num);
TimeUnit.SECONDS.sleep(1);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
out.close();
}
}
public static class ClientIn extends Thread {
private BufferedReader in;
public ClientIn(BufferedReader in) {
this.in = in;
}
#Override
public void run() {
}
}
}
public class Master {
private int slavePort;
private int clientPort;
private SlaveThread slaveThread;
private ClientThread clientThread;
private boolean running = false;
public static int slaveConnected; // Slave connection counter
public Master(int slavePort, int clientPort) {
this.slavePort = slavePort;
this.clientPort = clientPort;
this.slaveConnected = 0;
public void startServer() {
try {
this.slaveThread = new SlaveThread(slavePort);
this.clientThread = new ClientThread(clientPort);
System.out.println( "Αναμονή για σύνδεση client / slave" );
slaveThread.start();
clientThread.start();
} catch (IOException e) {
e.printStackTrace();
}
}
public void stopServer() {
running = false;
this.slaveThread.interrupt();
this.clientThread.interrupt();
}
class SlaveThread extends Thread {
private ServerSocket slaveSocket;
SlaveThread(int slavePort) throws IOException {
this.slaveSocket = new ServerSocket(slavePort);
}
#Override
public void run() {
running = true;
while (running) {
try {
// Call accept() to receive the next connection
Socket slSocket = slaveSocket.accept();
System.out.println("Δημιουργήθηκε μια νέα σύνδεση Slave");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class ClientThread extends Thread {
private ServerSocket clientSocket;
ClientThread(int clientPort) throws IOException {
this.clientSocket = new ServerSocket(clientPort);
}
#Override
public void run() {
running = true;
while (running) {
try {
Socket clSocket = clientSocket.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(clSocket.getInputStream()));
System.out.println("Δημιουργήθηκε μια νέα σύνδεση Client");
String inputLine;
while ((inputLine = in.readLine()) != null) {
System.out.println("Client: " + inputLine);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
Master server = new Master( 30091, 18889);
server.startServer();
// Automatically shutdown in 1 minute
try {
Thread.sleep( 60000 );
} catch(Exception e) {
e.printStackTrace();
}
server.stopServer();
}

I found the solution.
The Socket should be created on the Client Thread constructor and not to be passed as reference.
So the client should be
public class Client {
private static final int NUMBERS = 50;
private static final int AMPLITUDE = 100;
private static int masterPort;
public Client(int port) {
this.masterPort = port;
}
public static void main(String[] args) throws IOException{
String serverHostname = "127.0.0.1"; //Ορίζουμε την διεύθυνση που είναι ο σέρβερ
System.out.println("Αναμονή για σύνδεση στον σέρβερ " + serverHostname + " στην πόρτα 30091.");
ClientOut clientOut = new ClientOut(serverHostname);
clientOut.start();
ClientIn clientIn = new ClientIn(serverHostname);
clientIn.start();
}
public static class ClientOut extends Thread {
private Socket echoSocket;
private PrintWriter writer;
ClientOut(String serverHostname) throws IOException {
this.echoSocket = new Socket(serverHostname, 18889);
this.writer = new PrintWriter(echoSocket.getOutputStream(), true);;
}
#Override
public void run() {
System.out.println("Ο client συνδέθηκε!");
Random rnd = new Random();
try {
for (int i=0; i<NUMBERS; i++) {
int num = rnd.nextInt(AMPLITUDE);
System.out.println(num);
writer.println(num);
TimeUnit.SECONDS.sleep(1);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
writer.close();
}
}

Related

Cannot invoke "java.net.ServerSocket.close()" because "Server.server" is null

I'm trying to write a simple client/server application. I have a data on a client's side, that turns into an integer array and transfers to server. The server makes the calcutaions and returns them to client. But my program falls with this exception.
Sorry for long text, I'm just studying and really need your help.
public class Client {
private static Socket clientSocket;
private static ObjectInputStream in;
private static ObjectOutputStream out;
private static int[] parsedValue;
public Client(String input) {
try {
parsedValue = Arrays.stream(input.split(",")).mapToInt(Integer::parseInt).toArray();
} catch (Exception e) {
e.printStackTrace();
}
}
public Client(int[] input) {
parsedValue = input;
}
public Client(List<Integer> input) {
try {
parsedValue = input.stream().mapToInt(d->d).toArray();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
try {
try {
clientSocket = new Socket("localhost", 4004);
in = new ObjectInputStream(clientSocket.getInputStream());
out = new ObjectOutputStream(clientSocket.getOutputStream());
String clientTestString = "440,5,16";
Client stringClient = new Client(clientTestString);
out.writeObject(stringClient.parsedValue);
out.flush();
System.out.println(in.readObject());
int[] clientIntsTest = {39, 10, 5};
Client arrayClient = new Client(clientIntsTest);
out.writeObject(arrayClient.parsedValue);
out.flush();
System.out.println(in.readObject());
List<Integer> clientsTestList = Arrays.asList(781, 9, 7);
Client listClient = new Client(clientsTestList);
out.writeObject(listClient.parsedValue);
out.flush();
System.out.println(in.readObject());
} finally {
System.out.println("Client was closed");
clientSocket.close();
in.close();
out.close();
}
} catch (IOException | ClassNotFoundException e) {
System.err.println(e);
}
}
}
public class Server {
private static Socket clientSocket;
private static ServerSocket server;
private static ObjectInputStream in;
private static ObjectOutputStream out;
private static int[] parsedValue;
public String getResult() {
return calculation(parsedValue);
}
public String calculation(int[] parsedValue) {
parsedValue[0] = toDecimal(parsedValue[0], parsedValue[1]);
String answer = "";
int temp = 0;
String digits = new String("ABCDEF");
while (parsedValue[0] > 0) {
temp = parsedValue[0] % parsedValue[2];
if (temp < 10) {
answer = temp + answer;
} else {
answer = digits.charAt(temp - 10) + answer;
}
parsedValue[0] /= parsedValue[2];
}
return answer;
}
public int toDecimal(int value, int baseNotation) {
int i = 0;
int decimalNumber = 0;
if (value > 0) {
while (value != 0) {
decimalNumber += (value % 10) * Math.pow(baseNotation, i);
value /= 10;
i++;
}
}
return decimalNumber;
}
public static void main(String[] args) {
try {
try {
server = new ServerSocket(4004);
System.out.println("Server runs");
clientSocket = server.accept();
try {
in = new ObjectInputStream(clientSocket.getInputStream());
out = new ObjectOutputStream(clientSocket.getOutputStream());
parsedValue = (int[]) in.readObject();
System.out.println(parsedValue);
Server examp = new Server();
String answer = examp.getResult();
System.out.println(answer);
out.writeObject(answer);
out.flush();
} finally {
clientSocket.close();
in.close();
out.close();
}
} finally {
System.out.println("Server closed");
server.close();
}
} catch (IOException | ClassNotFoundException e) {
System.err.println(e);
}
}
}
In this two lines
Server examp = new Server();
String answer = examp.getResult();
you cretat a new object which overriddes the field private static ServerSocket server;
A better solution is to put the logic from your main() into a seperate method like run(), instantiate in main() a new object of server and call the run() on it. Dont't forget to make all fields as instance members by removing the static keyword.
public static void main(String[] args) {
Server examp = new Server();
examp.run();
}
public void run() {
try {
try {
server = new ServerSocket(4004);
System.out.println("Server runs");
clientSocket = server.accept();
try {
in = new ObjectInputStream(clientSocket.getInputStream());
out = new ObjectOutputStream(clientSocket.getOutputStream());
parsedValue = (int[]) in.readObject();
System.out.println(parsedValue);
String answer = getResult();
System.out.println(answer);
out.writeObject(answer);
out.flush();
} finally {
clientSocket.close();
in.close();
out.close();
}
} finally {
System.out.println("Server closed");
server.close();
}
} catch (IOException | ClassNotFoundException e) {
System.err.println(e);
}
}
By the way: You should always use this patern to get out of the 'static-trap'. So I suggest you refactor your Client calss too.

Java Server-Client with Multiple Client

I have been trying to make a multiple client chatting apps for a few days, and I have read the document below, and find some suggestions online, and I come up with the below code.
https://docs.oracle.com/javase/tutorial/networking/sockets/clientServer.html#later
What I am thinking is to make an app and start the Server, and Send the Message by the methods
"startServer();" and
"sendFromServer(Serializable data)";
~~~~~The Problem is I start startServer() method the app turn frozen, so I know I am doing it the wrong way.~~~~~~~~
Can anyone please give me some hint on how to correctly create a multiple client-server app?
public class Server {
private ServerSocket server;
private Socket socket;
private int port;
private Consumer<Serializable> consume;
private ConnectionThread thread;
private List<ConnectionThread> threads =
new ArrayList<ConnectionThread>();
public Server(int port, Consumer<Serializable> consume){
this.port= port;
this.consume = consume;
try {
server = new ServerSocket(port);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void startServer() {
if(server == null) {
System.out.println("no server");
}
while(true) {
try {
socket = server.accept();
} catch (IOException e) {
e.printStackTrace();
}
ConnectionThread thread =new ConnectionThread(socket);
threads.add(thread);
thread.start();
}
}
public void sendFromServer(Serializable data) throws IOException {
thread.out.writeObject(data);
}
private class ConnectionThread extends Thread {
private Socket socket;
private ObjectOutputStream out;
private ConnectionThread(Socket socket){
this.socket = socket;
}
#Override
public void run(){
try {
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
this.out = out;
while(true){
Serializable data = (Serializable)in.readObject();
consume.accept(data);
}
}catch (IOException e){
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
Client Side: (I am trying to make one Pane holding the two chats at the moment, using two buttons to call the"startServer();" and "startClient();" respectively)
public class Client {
private int port;
private String ip;
private Consumer<Serializable> consume;
private ConnectionThread thread = new ConnectionThread();
public Client(int port, String ip, Consumer<Serializable> consume){
this.port = port;
this.ip = ip;
this.consume = consume;
}
public void startClient(){
thread.start();
}
public void sendFromClient(Serializable data) throws IOException{
thread.out.writeObject(data);
}
private class ConnectionThread extends Thread{
private Socket socket;
private ObjectOutputStream out;
#Override
public void run(){
try(
Socket socket = new Socket(ip, port);
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
) {
this.out = out;
while(true){
Serializable data = (Serializable)in.readObject();
consume.accept(data);
}
} catch (Exception e) {
e.printStackTrace();;
}
}
}
}
the FXML controller class
public class chatController{
#FXML private TextArea SerBoard, CliBoard;
#FXML private TextField SerTxt,CliTxt;
#FXML private Button SerConnect, CliConnect;
private Server server = createSer();
private Client client = createCli();
private int port= 5555;
private String ip = "localhost";
private boolean connected =
(server==null && client==null)? false: true;
#FXML
public void setOnSerConnect(ActionEvent event) {
server.startServer();
}
#FXML
public void setOnCliConnect(ActionEvent event) {
client.startClient();
}
private Client createCli() {
Client client = new Client(port, ip, data->{
Platform.runLater(() -> {
CliBoard.appendText(data.toString());
});
});
System.out.println("Client connect");
return client;
}
private Server createSer() {
Server server = new Server(port, data->{
Platform.runLater(()->{
SerBoard.appendText(data.toString());
});
});
System.out.println("Server connect");
return server;
}
#FXML
public void setOnSerText(ActionEvent event) {
if(connected) {
String input = SerTxt.getText();
String mes = "Server: "+ input + "\n";
SerTxt.clear();
SerBoard.appendText(mes);
try {
server.sendFromServer(mes);
} catch (IOException e) {
e.printStackTrace();
}
}
}
#FXML
public void setOnCliText(ActionEvent event) {
if(connected) {
String input = SerTxt.getText();
String mes = "Client: "+ input + "\n";
SerTxt.clear();
SerBoard.appendText(mes);
try {
client.sendFromClient(mes);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Should be rather
public void startServer() {
if(server == null) {
System.out.println("no server");
}
while(true) {
try {
socket = server.accept();
ConnectionThread thread =new ConnectionThread(socket);
threads.add(thread);
thread.start();
} catch (IOException e) {
e.printStackTrace();
}
}
This way u will acceppt all client connections.
Also startServer must be invoked using Platform.runLater as well.

How to use Java Socket with Runnable

I want to call a function cycle() that do something for every some x second.
At this time i can call it only when it has a request from client.
public class ChatServer implements Runnable {
private static final int PORT = 9001;
private static HashSet<String> names = new HashSet<String>();
private static HashSet<PrintWriter> writers = new HashSet<PrintWriter>();
public static void main(String[] args) throws Exception {
System.out.println("The chat server is running.");
ServerSocket listener = new ServerSocket(PORT);
try {
while (true) {
new Handler(listener.accept()).start();
}
} finally {
listener.close();
}
}
private static class Handler extends Thread {
private String name;
private Socket socket;
private BufferedReader in;
private PrintWriter out;
public Handler(Socket socket) {
this.socket = socket;
}
public void run() {
cycle();
try {
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
while (true) {
out.println("SUBMITNAME");
name = in.readLine();
if (name == null) {
return;
}
synchronized (names) {
if (!names.contains(name)) {
names.add(name);
break;
}
}
}
out.println("NAMEACCEPTED");
writers.add(out);
while (true) {
String input = in.readLine();
if (input == null) {
return;
}
for (PrintWriter writer : writers) {
writer.println("MESSAGE " + name + ": " + input);
}
}
} catch (IOException e) {
System.out.println(e);
} finally {
if (name != null) {
names.remove(name);
}
if (out != null) {
writers.remove(out);
}
try {
socket.close();
} catch (IOException e) {
}
}
}
}
}
Yeah, code below is work when i remove Handle class from my code.
My problem is i can't combine them together, please help or suggest. Many thanks.
private void cycle() {
//do something
}
#Override
public void run() {
long beforeTime, timeDiff, sleep;
beforeTime = System.currentTimeMillis();
while (true) {
cycle();
timeDiff = System.currentTimeMillis() - beforeTime;
sleep = DELAY - timeDiff;
if (sleep < 0) {
sleep = 2;
}
try {
Thread.sleep(sleep);
} catch (InterruptedException e) {
System.out.println("Interrupted: " + e.getMessage());
}
beforeTime = System.currentTimeMillis();
}
}
Do you try to start a separate thread for the cycle function before call listen to the socket.
public static void main(String[] args) throws Exception {
System.out.println("The chat server is running.");
//start separate thread to keep loop....
new Thread(new ChatServer()).start();
ServerSocket listener = new ServerSocket(PORT);
try {
while (true) {
new Handler(listener.accept()).start();
}
} finally {
listener.close();
}
}

Chat Application using socket not working over Internet in Java

I am currently developing chat application working over Internet.currently my application working fine over LAN but not working over Internet.I have also used port forwarding.I have done setting in modem and forward the port to private IP address but still it's not working.I got the error that "server isn't found".Please suggest me what I have to do and tell,Am I done the correct setting in modem or not??
Below is my server code...
Server.java
import java.util.*;
import java.net.*;
import java.io.*;
class Server implements ChatConstants
{
private static Vector list;
private ServerSocket ssocket ;
private Service service;
private static Socket socket;
private boolean done=false;
private static Hashtable userTable = new Hashtable();
private static Hashtable _userList = new Hashtable();
private static Hashtable _conflist = new Hashtable();
public Server() throws UnknownHostException
{
System.out.println("Initializing...");
list=new Vector(BACKLOG);
try {
ssocket= new ServerSocket(SERVER_PORT,BACKLOG);
}
catch(Exception e) {
e.printStackTrace();
System.out.println("Inside constructor"+e);
}
start();
}
public void start() throws UnknownHostException
{
byte[] data;
int header;
Socket _socket = null;
String hostname = null;
System.out.println("Server successfully started at "
+InetAddress.getLocalHost().toString()
+" port "+SERVER_PORT);
while(!done) {
try
{
_socket=ssocket.accept();
if(_socket != null) {
synchronized(list) {
list.addElement(_socket);
}
DataInputStream dis=new DataInputStream(_socket.getInputStream());
data = new byte[MAX_MESSAGE_SIZE];
dis.read(data);
Message message = ((Message)ChatUtils.bytesToObject(data));
System.out.println("Joined client "
+message._username+" at "+message._host+"...");
synchronized(userTable) {
userTable.put(message._username,_socket);
}
addUser(message);
sendUserList(message);
writeToClients(message);
service = new Service(_socket,hostname,message._user);
}
}
catch(Exception e) {
e.printStackTrace();
System.out.println("Thread exception"+e);
try {
_socket.close();
}
catch(Exception ex) {
ex.printStackTrace();
System.out.println("ERROR CLOSING SOCKET");
}
}
}//END WHILE
}
private void addUser(Message message)
{
synchronized(_userList) {
_userList.put(message._user.toString(),message._user);
}
}
public static void updateUser(User user)
{
User myuser;
synchronized(_userList) {
_userList.put(user.toString(),user);
}
}
public static synchronized void writeToClients(Message message)
{
byte[] data;
DataOutputStream dos;
for(int count=0;count<list.size();count++) {
try {
dos=new
DataOutputStream(((Socket)list.elementAt(count)).getOutputStream());
data=ChatUtils.objectToBytes(message);
dos.write(data,0,data.length);
}
catch(Exception e) {
e.printStackTrace();
System.out.println("Output exception");
}
}//END FOR
}
public static void writeToClient(Message message)
{
Socket socket;
byte[] data;
DataOutputStream dos;
synchronized(userTable) {
try {
socket = (Socket)userTable.get(message._destination);
dos=new DataOutputStream(socket.getOutputStream());
data=ChatUtils.objectToBytes(message);
dos.write(data,0,data.length);
}
catch(Exception e) {
e.printStackTrace();
System.out.println("SEND EXCEPTION"+e);
}
}
}
public static void sendConferenceListToClient(Message message)
{
Socket socket;
byte[] data;
DataOutputStream dos;
synchronized(userTable) {
try {
Message mymessage= new Message(CONFERENCE_LIST);
Vector vector = (Vector)
_conflist.get(message._destination);
mymessage._username = message._username;
mymessage._destination = message._destination;
mymessage.userlist = vector;
socket = (Socket)userTable.get(message._username);
if(socket!=null) {
dos=new DataOutputStream(socket.getOutputStream());
data=ChatUtils.objectToBytes(mymessage);
dos.write(data,0,data.length);
}
}
catch(Exception e) {
e.printStackTrace();
System.out.println("CONFERENCE LIST EXCEPTION"+e);
}
}
}
public static void writeToPublicChat(Message message)
{
Socket socket;
byte[] data;
DataOutputStream dos;
synchronized(_conflist) {
try {
Vector svector = (Vector)_conflist.get(message._destination);
for(int cnt=0;cnt<svector.size();cnt++) {
synchronized(userTable) {
try {
socket = (Socket)userTable.get((svector.get(cnt).toString()));
if(socket!=null) {
dos=new DataOutputStream(socket.getOutputStream());
data=ChatUtils.objectToBytes(message);
dos.write(data,0,data.length);
}
}
catch(Exception e) {
e.printStackTrace();
System.out.println("PUBLIC CHAT EXCEPTION"+e);
}
}
}
} catch(Exception e){
e.printStackTrace();
System.out.println("PUBLIC EXCEPTION"+e);
}
}
}
public static void inviteToPublicChat(Vector svector,Message message)
{
Socket socket;
byte[] data;
DataOutputStream dos;
synchronized(_conflist) {
for(int cnt=0;cnt<svector.size();cnt++) {
synchronized(userTable) {
try {
socket = (Socket)userTable.get((svector.get(cnt).toString()));
if(socket != null) {
dos=new DataOutputStream(socket.getOutputStream());
data=ChatUtils.objectToBytes(message);
dos.write(data,0,data.length);
}
}
catch(Exception e) {
e.printStackTrace();
System.out.println("PUBLIC INVITE EXCEPTION"+e);
}
}
}
}
}
private void sendUserList(Message message)
{
int header=0;
String destination;
header=message._header;
destination = message._destination;
message._header = USERS_LIST;
message._destination = message._username;
message.userlist = new Vector(_userList.values());
writeToClient(message);
//Restore the headers
message._destination = destination;
message._header = header;
}
public static synchronized void removeUser(User user)
{
try {
Socket socket = (Socket)userTable.get(user.toString());
list.removeElement(socket);
_userList.remove(user.toString());
userTable.remove(user.toString());
}
catch(Exception e) {
e.printStackTrace();
System.out.println("ERROR REMOVING SOCKET "+e);
}
}
public static synchronized void processClientMessage(Message message)
{
switch(message._header) {
case CHANGE_STATUS:
updateUser(message._user);
writeToClients(message);
break;
case CLIENT_LOGOUT:
removeUser(message._user);
writeToClients(message);
break;
case CONFERENCE_CREATE:
Vector myvector = new Vector();
myvector.add(message._username);
_conflist.put(message._user.toString(),myvector);
case CONFERENCE_INVITE:
inviteToPublicChat(message.userlist,message);
break;
case CONFERENCE_JOIN:
Vector vector=null;
vector = (Vector)
_conflist.get(message._destination.toString());
vector.add(message._username);
_conflist.put(message._destination.toString(),vector);
writeToPublicChat(message);
break;
case CONFERENCE_DENY:
//_conflist.remove(message._user.toString(),message.userlist);
writeToPublicChat(message);
break;
case CONFERENCE_LEAVE:
Vector vectors =(Vector)
_conflist.get(message._destination.toString());
for(int count=0;count<vectors.size();count++) {
if(message._username.equals((vectors.elementAt(count).toString())))
vectors.remove(count);
}
if(vectors.size() != 0)
_conflist.put(message._user.toString(),vectors);
else//IF THERE ARE NO MORE USERS
_conflist.remove(message._user.toString());//DONE CONFERENCE
writeToPublicChat(message);
break;
case PUBLIC_CHAT:
writeToPublicChat(message);
break;
case CONFERENCE_LIST:
sendConferenceListToClient(message);
break;
default:
writeToClient(message);
}
}
public static void main(String args[]) throws Exception
{
Server chatserver=new Server();
}
}
//
// Service: Service class for each clients connected to server.
//
class Service implements Runnable, ChatConstants
{
private DataInputStream dis;
private Socket socket;
private boolean done=false;
private Thread thread;
private String hostname;
private User user;
public Service(Socket _socket,String _hostname,User user)
{
try {
this.socket = _socket;
this.hostname=_hostname;
this.user = user;
dis=new DataInputStream(socket.getInputStream());
thread=new Thread(this,"SERVICE");
thread.start();
}
catch(Exception e){
e.printStackTrace();
System.out.println("service constructor"+e);
}
}
public void run()
{
byte[] data;
while(!done)
{
try {
data = new byte[MAX_MESSAGE_SIZE];
dis.read(data);
Message message = ((Message)ChatUtils.bytesToObject(data));
Server.processClientMessage(message);
}
catch(Exception e) {
e.printStackTrace();
done = true;
Server.removeUser(user);
Message message = new Message(CLIENT_LOGOUT);
user.isOnline = OFFLINE;
message._user = user;
Server.writeToClients(message);
try {
socket.close();
} catch(Exception se) {
se.printStackTrace();
System.out.println("ERROR CLOSING SOCKET "+se);
}
//System.out.println("SERVICE THREAD EXCEPTION"+e);
}
}//END WHILE
}
}
Thanks in advance.
I think the
ssocket= new ServerSocket(SERVER_PORT,BACKLOG);
is making the issue. Use the version
ssocket= new ServerSocket(SERVER_PORT,BACKLOG,LOCAL_INET_ADDRESS);
and bind server to some constant local IP. Now use the port forwarding in the modem, to forward all requests to that local ip. Make sure that the firewall is not preventing you to use the port. Since firewall may allow a local networking but not to web.

java socket programming problem (sending and receiving data)

Client has sendpoints() method which is called by some other class that I did not include.
Anyways, sendpoints() is called and sends integers to the server, which receives them and send back to all the clients that are connected to the server(broadcast).
The problem is, clients keep sending integers while server is stuck in the thread I created for receiving integers(I think the server is not reading from inputstream).
I tried changing the stream, I tried putting integers together in a object and send it with ObjectOutputStream but none of these seems to work.
I need help (pointStruct is a class that holds some integer values I created)
import java.net.*;
import java.util.*;
import java.awt.*;
import java.io.*;
import javax.swing.*;
public class Server {
private ArrayList dataclient;
private ArrayList messageclient;
private ServerSocket dataserver;
private ServerSocket messageserver;
public static void main(String[] args) {
Server s1 = new Server();
s1.start();
}
// Start running server
public void start() {
try {
dataserver = new ServerSocket(4999);
messageserver = new ServerSocket(5000);
Socket dataconn;
Socket messageconn;
dataclient = new ArrayList();
messageclient = new ArrayList();
dataconn= null;
messageconn= null;
System.out.println("[server]start");
//start accepting connections
while (true) {
try {
dataconn = dataserver.accept();
System.out.println("[server]accepted dataconn");
messageconn = messageserver.accept();
System.out.println("[server]accepted messageconn");
//add clients to arraylist
dataclient.add(dataconn.getOutputStream());
messageclient.add(messageconn.getOutputStream());
}
catch (Exception ex) {
ex.printStackTrace();
}
//creating receiver threads
Thread t1 = new Thread(new DataReceiver(dataconn));
Thread t2 = new Thread(new MessageReceiver(messageconn));
System.out.println("[server]Thread successfully created");
t1.start();
t2.start();
System.out.println("[server]Thread successfully started");
}
}
catch(Exception ex) {
ex.printStackTrace();
}
}
//receive data from clients
public class DataReceiver implements Runnable {
BufferedReader br;
InputStream is;
int x,y;
int x2,y2;
int t;
int red;
int green;
int blue;
int size;
int dummy;
DataReceiver(Socket s){
try {
is=s.getInputStream();
//br = new BufferedReader(isr);
}
catch(Exception ex) {
ex.printStackTrace();
}
}
public void run() {
while(true) {
try{
Iterator it = dataclient.iterator();
dummy=is.read();
if(dummy==9999) {
System.out.println("[server]executing data thread");
x=is.read();
System.out.println("[server]read a line"+x);
y=is.read();
System.out.println("[server]read a line"+y);
//x2=isr.read();
//y2=isr.read();
t=is.read();
red=is.read();
green=is.read();
blue=is.read();
size=is.read();
dummy=0;
//broadcast data
while (it.hasNext()) {
OutputStream os = (OutputStream)it.next();
os.write(9999);
os.write(x);
os.write(y);
os.write(t);
os.write(255);
os.write(0);
os.write(0);
os.write(size);
}
System.out.println("[server]data broadcasted");
}
}
catch(Exception ex) {
ex.printStackTrace();
}
}
}
}
//------------------------receive message from clients------------------------
public class MessageReceiver implements Runnable {
MessageReceiver(Socket s) {
}
public void run() {
}
}
}
public class networkHandler{
PrintWriter writer;
BufferedReader reader;
PrintWriter pwriter;
BufferedReader preader;
Socket sock;
Socket pointsock;
InputStream is;
JTextArea incoming;
pointHandler ph;
public networkHandler(pointHandler _ph) {
init();
ph=_ph;
setUpNetworking();
Thread readerThread = new Thread(new IncomingReader());
readerThread.start();
Thread pointerThread = new Thread(new ReceivingPoints());
pointerThread.start();
}
public void init() {
incoming = new JTextArea(20,20);
}
private void setUpNetworking() {
try {
// setup message port
System.out.println("networking establish started");
sock = new Socket("127.0.0.1",5000);
System.out.println("[NH]port 5000 established");
// setup point port
pointsock = new Socket("127.0.0.1",4999);
System.out.println("[NH]port 4999 established");
//message i/o stream
InputStreamReader streamReader = new InputStreamReader(sock.getInputStream());
reader = new BufferedReader(streamReader);
writer = new PrintWriter(sock.getOutputStream());
//point i/o stream
InputStreamReader pstreamReader = new InputStreamReader(pointsock.getInputStream());
System.out.println("networking establishing: Stream");
preader= new BufferedReader(pstreamReader);
pwriter= new PrintWriter(pointsock.getOutputStream());
System.out.println("networking establishing: Stream");
}
catch(IOException ex) {
ex.printStackTrace();
}
System.out.println("networking established");
}
//send message to the server
public void writeStream(String input){
try {
writer.println(input);
writer.flush();
}
catch(Exception ex) {
ex.printStackTrace();
}
}
public JTextArea getServerMessage() {
return incoming;
}
//receiving message from server
public class IncomingReader implements Runnable {
#Override
public void run() {
String message;
try {
while ((message = reader.readLine())!=null){
System.out.println("[NH] read from server:"+message);
incoming.append(message+"\n");
}
}
catch(Exception ex) {
ex.printStackTrace();
}
}
}
//receiving points from server
public class ReceivingPoints implements Runnable {
int x,y;
int x2,y2;
int red;
int green;
int blue;
int t;
int size;
int dummy;
pointStruct ps;
Color cr;
Point p;
synchronized public void run() {
try {
is = pointsock.getInputStream();
p= new Point();
}
catch(Exception ex) {
ex.printStackTrace();
}
while(true) {
try {
dummy=is.read();
if(dummy==9999) {
x=is.read();
y=is.read();
//x2=preader.read();
//y2=preader.read();
t=is.read();
red=is.read();
green=is.read();
blue =is.read();
size=is.read();
//create dummy pointStruct
ps = new pointStruct();
cr = new Color(red,green,blue);
p.x=x;
p.y=y;
ps.setP1(p);
p.x=x2;
p.y=y2;
//ps.setP2(p);
ps.setT((char)t);
ps.setS(size);
ps.setC(cr);
ph.save(ps);
dummy=0;
}
}
catch(Exception ex) {
ex.printStackTrace();
}
System.out.println("[NH]receiving done");
}
}}
public void sendPoints(pointStruct ps) {
OutputStream os;
try{
os=pointsock.getOutputStream();
os.write(9999);
os.write(ps.getP1().x);
os.write(ps.getP1().y);
//pwriter.print(ps.getP2().x);
//pwriter.print(ps.getP2().y);
os.write(ps.getT());
os.write(ps.getC().getRed());
os.write(ps.getC().getGreen());
os.write(ps.getC().getBlue());
os.write(ps.getS());
}
catch(Exception ex) {
ex.printStackTrace();
}
System.out.println("[NH]points sent to server");
}
}
You are reading the stream incorrectly, InputStream.read() returns a byte from the stream, but cast to an int.
InputStream.read() returns values from 0 to 255 is read is successful, and -1 if no more reading can be done (end of stream).
For example, InputStream.read() != 9999 always. So this ReceivingPoints.run() block will not fire:
while (true) {
try {
dummy = is.read();
if (dummy == 9999) {}
} catch(Exception ex) {
ex.printStackTrace();
}
}
You are looking for DataInputStream, it has methods for reading and writing other basic types than just bytes.

Categories

Resources