I',m currently having a problem with regards to my code. A client should be able to send a string "messge#somestring" and if the server notices that it contains the "message#" substring it should send it to all users. However, what is happening is that it gets sent to just one user that sent the "pseudo-request" that I'm trying to implement. Here are my codes for reference:
import java.io.*;
import java.net.*;
import java.util.Vector;
public class server {
static ServerSocket ss;
static Socket s;
static DataInputStream dis;
static DataOutputStream dos;
static Integer maxNumofUsers=4;
static Vector<UserHandler> users;
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
Integer currNumofUsers=0;
ss=new ServerSocket(7777);
users=new Vector<UserHandler>();
while(currNumofUsers<maxNumofUsers) {
s=ss.accept();
UserHandler uh= new UserHandler(s, "Player "+Integer.toString(currNumofUsers+1));
users.add(uh);
users.get(users.size()-1).start();//start a thread
currNumofUsers++;
for(int i=0; i<users.size(); i++) {//updates number of users present pero userhandler
users.get(i).updateUserSet(users);
}
}
System.out.println("Maximum number of players reached.");
}
}
class UserHandler extends Thread{
Socket s;
DataInputStream dis;
DataOutputStream dos;
Vector<UserHandler> users=new Vector<UserHandler>();
String username;
public UserHandler(Socket s, String username) {
// TODO Auto-generated constructor stub
this.s=s;
this.username=username;
}
public void run(){
try {
dis=new DataInputStream(s.getInputStream());
dos=new DataOutputStream(s.getOutputStream());
while(true) {
String message=dis.readUTF();
if(message.contentEquals("exit")) {
dos.writeUTF("exit granted");
close();
break;
}else if(message.contains("message#")){//group sms
for(int i=0; i<users.size(); i++) {
users.get(i).dos.writeUTF("henlo");
System.out.println("Wrote to "+users.get(i).username);
}
}else {
dos.writeUTF("Some String");
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
try {
s.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.printStackTrace();
}
}
public void close() {
try {
for(int i=0; i<users.size(); i++) {
if(users.get(i).username==this.username) {
users.remove(i);
System.out.println("out");
for(int j=0; j<users.size(); j++) {
users.get(j).updateUserSet(users);
}
break;
}
}
dis.close();
dos.close();
s.close();
}catch(IOException e) {
e.printStackTrace();
}
}
public void updateUserSet(Vector<UserHandler> users) {
// TODO Auto-generated method stub
this.users=users;
}
}
For the server. for the client,
import java.net.*;
import java.util.Scanner;
import java.io.*;
public class client {
static Socket s;
static DataInputStream dis;
static DataOutputStream dos;
static gameWindow GUI;
static String username;
public static void main(String[] args) throws Exception {
try {
s=new Socket();
s.connect(new InetSocketAddress("127.0.0.1",7777), 5000);
System.out.println("Socket "+s.getInetAddress()+" has connected.");
username= JOptionPane.showInputDialog("Please input username: ");
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("Cannot connect to server. Either the Server was not established or maximum number of players was reached.");
}
if(s.isConnected()){
try {
dis=new DataInputStream(s.getInputStream());
dos=new DataOutputStream(s.getOutputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Scanner sc=new Scanner(System.in);
String msg;
while(true) {
msg=sc.nextLine();
dos.writeUTF(msg);
String rcv=dis.readUTF();
if (rcv.contentEquals("exit granted")) {
System.out.println("Socket "+s.getInetAddress()+" is closed.");
close();
break;
}else if(rcv.contains("array#")) {
String tobearr=rcv;
String[] arred=tobearr.split("#");
for(int i=0; i<arred.length; i++) {
System.out.println(arred[i]);
}
tobearr="";
}else if(rcv.contains("message#")) {
String grpsms=rcv.substring(8, rcv.length());
System.out.println(grpsms);
}
System.out.println(rcv);
rcv="";
}
}
}
private static void close() {
// TODO Auto-generated method stub
try {
dis.close();
dos.close();
s.close();
}catch(IOException e) {
e.printStackTrace();
}
}
}
Related
I have a socket that is consuming 100% of the computer's CPU.
There are 150 clients sending messages to the server every 30 seconds unsynchronously.
Does anyone know how to solve this problem?
Below is my ServerSocket class
public class Servidor {
static ExecutorService es;
public static void main(String[] args) throws Exception {
es = Executors.newFixedThreadPool(150);
ServerSocket servidor = new ServerSocket(2010);
while (true) {
Socket soquete = null;
try {
System.out.println("Aguardando cliente: ");
soquete = servidor.accept();
System.out.println("Cliente Conectado: ");
es.execute(new Conexao(soquete));
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
The Conexao class (utility class) takes the string sent by the clients and saves it in the database.
Below my Conexao class
public class Conexao implements Runnable{
Socket soquete;
int contador = 0;
public Conexao(Socket soquete) {
super();
this.soquete = soquete;
}
#Override
public void run(){
BufferedReader in = null;
try{
in = new BufferedReader(new InputStreamReader(soquete.getInputStream()));
while (!in.ready()) {/*System.out.println("!in.ready()");*/}
String str =in.readLine();
System.out.println("Rodando Thread"+Thread.currentThread().getName() + " : texto: " + str);
}finally{
...
if(soquete != null){
try {
soquete.close();
} catch (IOException e) {
// TODO Auto-generated catch block
}
}
}
}
}
I solved the problem by removing part "while (!in.ready()) {/System.out.println("!in.ready()");/}" and creating a "Thread.sleep" at the end of the try block
I need to limit the number of client that can connect to the server . I only want 3 clients that can connect not more.
I tried if else conditions. and some loops.
public class server {
ServerSocket ss;
boolean quite=false;
ArrayList<MultiServerConnection> OurDomainsConnections=new ArrayList<MultiServerConnection>();
public static void main(String[] args) {
new server();
}
public server() {
try {
//TODO use method to take this as an input from user)
ss=new ServerSocket(3333);//here we are using connection 3333 (change as you want
while(!quite)
{
Socket s=ss.accept();//when a connection to the domain is found we accept it
MultiServerConnection OurConnection = new MultiServerConnection(s,this);
OurConnection.start();//Start Thread
OurDomainsConnections.add(OurConnection);//add connection to our Domain Connection
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}//make sure its bloody same with client it took my 15 min to realize that XD
}
}
public class MultiServerConnection extends Thread {
Socket s;
DataInputStream din;
DataOutputStream dout;
server ss;
boolean quite=false;
public MultiServerConnection(Socket OurSocket,server OurServer)
{
super("MultiServerConnection");//server connection thread
this.s=OurSocket;
this.ss=OurServer;
}
public void ServerOutClientIn(String OutText)
{
try {
long ThreadID=this.getId();
dout.writeUTF(OutText);
dout.flush();//this is because of a buffer error :<
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void ServerOutAllClientIn(String OutText)
{
for(int i=0;i<ss.OurDomainsConnections.size();i++)
{
MultiServerConnection Connection=ss.OurDomainsConnections.get(i);
Connection.ServerOutClientIn(OutText);
}
}
public void run()
{
try {
din=new DataInputStream(s.getInputStream());
dout=new DataOutputStream(s.getOutputStream());
while(!quite)
{
while(din.available()==0)
{
try {
Thread.sleep(1);//sleep if there is not data coming
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
String ComingText=din.readUTF();
ServerOutAllClientIn(ComingText);
}
din.close();
dout.close();
s.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class MultiClients extends Thread {
Socket s;
DataInputStream din;
DataOutputStream dout;
boolean quite=false;
public ClientData c;
public interface1 GUI;
public MultiClients(Socket OurMultiSocket, interface1 gui)
{
s=OurMultiSocket;
c=new ClientData();
GUI=gui;
}
public void ClientOutServerIn(String Text)
{
//write the line from console to server
try {
if(Text.equals("change channel"))
{
System.out.print("sending changing channel: "+Text+"\n");
dout.writeUTF(Text);
dout.flush();
}
else if(Text.equals("new user"))
{
System.out.print("sending new user: "+ Text+"\n");
dout.writeUTF(Text+":"+c.GetName()+"="+c.GetChannel());
dout.flush();
}
else
{
dout.writeUTF(c.GetChannel()+"="+this.getName()+": "+Text);
dout.flush();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void SetClient(String channel,String Name)
{
c.SetName(Name);
c.SetChannel(channel);
}
public void run()
{
try {
din=new DataInputStream(s.getInputStream());
dout=new DataOutputStream(s.getOutputStream());
while(!quite)
{
try {
while(din.available()==0)
{
try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//if there is something just show it on console
//and then go back and do the same
String reply=din.readUTF();
String Chan=ExtractChannel(reply);
String name=ExtractName(reply);
/*if (reply.equals("change channel"))
{
System.out.print("changing channel in body: "+reply+"\n");
//GUI.ClearDisplay();
setChangedChannel();
}*/
if(name.equals("new user"))
{
System.out.print("new user in body: "+reply+"\n");
//GUI.ClearDisplay();
setChannel(reply);
}
else
{
PrintReply(Chan,reply);
}
//System.out.println(reply);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
try {
din.close();
dout.close();
s.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
try {
din.close();
dout.close();
s.close();
} catch (IOException x) {
// TODO Auto-generated catch block
x.printStackTrace();
}
}
}
public void CloseClient()
{
try {
din.close();
dout.close();
s.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public String ExtractName(String x)
{
String[]Y=x.split(":");
return Y[0];
}
public String ExtractChannel(String X)
{
String[]Y=X.split("=");
return Y[0];
}
public void PrintReply(String Chan,String Rep)
{
if(c.GetChannel().equals(Chan))
{
String []Y=Rep.split("=");
GUI.setDisplay(Y[1]);
//System.out.println(Y[1]+"\n \n \n \n");
}
}
public void setChannel(String x)
{
String []Y=x.split(":");
String []Z=Y[1].split("=");
System.out.print("setting "+Z[0]+" channel to "+Z[1]+"\n");
GUI.setUserInChannel(Z[0]);
}
public void setChangedChannel()
{
GUI.setUserInChannel(c.GetName()+": "+c.GetChannel());
}
class ClientData
{
public String ClientName;
public String channel;
public void SetChannel(String Chan)
{
channel=Chan;
}
public void SetName(String name)
{
ClientName=name;
}
public String GetChannel()
{
return channel;
}
public String GetName()
{
return ClientName;
}
}
}
in this code. more than 5 user can can chat together. i only want to allow 3 user to connect and to chat.
You can use AtomicInteger as a counter to check how many clients you have already connected:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicInteger;
public class server {
ServerSocket ss;
boolean quite=false;
ArrayList<MultiServerConnection> OurDomainsConnections=new ArrayList<MultiServerConnection>();
final AtomicInteger runningCount = new AtomicInteger(0);
final Integer limit = 3;
public static void main(String[] args) {
new server();
}
public server() {
try {
//TODO use method to take this as an input from user)
ss=new ServerSocket(3333);//here we are using connection 3333 (change as you want
while(!quite)
{
Socket s=ss.accept();//when a connection to the domain is found we accept it
if (runningCount.incrementAndGet() < limit){ //increment number of clients and check
MultiServerConnection OurConnection = new MultiServerConnection(s,this, runningCount::decrementAndGet);
OurConnection.start();//Start Thread
OurDomainsConnections.add(OurConnection);//add connection to our Domain Connection
} else {
runningCount.decrementAndGet();
s.close();
System.out.println("limit exceeded");
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}//make sure its bloody same with client it took my 15 min to realize that XD
}
}
interface Callback {
void call();
}
class MultiServerConnection extends Thread {
Socket s;
DataInputStream din;
DataOutputStream dout;
server ss;
boolean quite=false;
final Callback callbackOnFinish;
public MultiServerConnection(Socket OurSocket,server OurServer, Callback callbackOnFinish)
{
super("MultiServerConnection");//server connection thread
this.s=OurSocket;
this.ss=OurServer;
this.callbackOnFinish = callbackOnFinish;
}
public void ServerOutClientIn(String OutText)
{
try {
long ThreadID=this.getId();
dout.writeUTF(OutText);
dout.flush();//this is because of a buffer error :<
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void ServerOutAllClientIn(String OutText)
{
for(int i=0;i<ss.OurDomainsConnections.size();i++)
{
MultiServerConnection Connection=ss.OurDomainsConnections.get(i);
Connection.ServerOutClientIn(OutText);
}
}
public void run()
{
try {
din=new DataInputStream(s.getInputStream());
dout=new DataOutputStream(s.getOutputStream());
while(!quite)
{
while(din.available()==0)
{
try {
Thread.sleep(1);//sleep if there is not data coming
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
String ComingText=din.readUTF();
ServerOutAllClientIn(ComingText);
}
din.close();
dout.close();
s.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
callbackOnFinish.call();
}
}
}
When a new connection is accepted runningCount is atomically increased and value is got by runningCount.incrementAndGet(). Then if value below the limit - new MultiServerConnection is created with a callback. The callback is used for decrementing a counter on exit. If counter equal or above the limit => socket will be closed and error message printed. It is good to have a message passed to the socket.
P.S. I have not reviewed your solution. I've just added the feture you requested.
I want to create a class that contain two socket I.e socket for client1 and socket for client 2 so that they can chat together.
How can I achieve this.When i run above code i am getting stream corrupted exception .
My chat is not working. Can someone help me out ?
Here is my code .
This is client code for making socket request
Client.java
package customChat;
import java.net.*;
import java.io.*;
import java.util.*;
public class Client
{
private String notif = " *** ";
private ObjectInputStream sInput;
private ObjectOutputStream sOutput;
private Socket socket;
private String server, username;
private int port;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
private RemoteAccess access;
Client(String server, int port,RemoteAccess access ) {
this.server = server;
this.port = port;
this.access = access;
}
public boolean start()
{
try
{
socket = new Socket(server, port);
}
catch(Exception ec) {
display("Error connectiong to server:" + ec);
return false;
}
String msg = "Connection accepted " + socket.getInetAddress() + ":" + socket.getPort();
display(msg);
try
{
sInput= new ObjectInputStream(socket.getInputStream());
sOutput = new ObjectOutputStream(socket.getOutputStream());
}
catch (IOException eIO) {
eIO.printStackTrace();
display("Exception creating new Input/output Streams in client: " + eIO);
return false;
}
new ListenFromServer().start();
try
{
sOutput.writeObject(access);
}
catch (IOException eIO) {
display("Exception doing login : " + eIO);
//disconnect();
return false;
}
return true;
}
private void display(String msg)
{
System.out.println(msg);
}
void sendMessage(RemoteAccess msg)
{
try
{
System.out.println("I am writing for :"+msg.getTo()+": msg "+msg.getMsg());
sOutput.writeObject(msg);
}
catch(IOException e) {
display("Exception writing to server: " + e);
}
}
private void disconnect() {
try {
if(sInput != null) sInput.close();
}
catch(Exception e)
{
e.printStackTrace();
}
try {
if(sOutput != null) sOutput.close();
}
catch(Exception e) {
e.printStackTrace();
}
try{
if(socket != null) socket.close();
}
catch(Exception e) {
e.printStackTrace();
}
}
public static void sendFile()
{
int portNumber = 1502;
String serverAddress = "localhost";
Scanner scan = new Scanner(System.in);
System.out.println("Enter from ");
long from = scan.nextLong();
System.out.println("Enter to");
long to = scan.nextLong();
RemoteAccess access = new RemoteAccess(to,from,"hello");
Client client = new Client(serverAddress, portNumber,access);
if(!client.start())
return;
while(true)
{
System.out.println("Please enter msg:");
System.out.print("> ");
// read message from user
String msg = scan.nextLine();
System.out.println("Sending message");
client.sendMessage(new RemoteAccess(to,from,msg));
}
}
public static void main(String[] args)
{
sendFile();
}
class ListenFromServer extends Thread {
public void run()
{
System.out.println("i am in run method");
while(true)
{
System.out.println("i am in run method 2");
try
{
System.out.println("i am in run method 3");
RemoteAccess access = (RemoteAccess) sInput.readObject();
System.out.println("Message read by:"+access.getFrom());
if(access !=null)
{
System.out.println("Message is :"+access.getFrom());
}
}
catch(IOException e)
{
e.printStackTrace();
System.out.println("Excepion caught while listening from server :"+e);
display(notif + "Server has closed the connection: " + e + notif);
break;
}
catch(ClassNotFoundException e2) {
e2.printStackTrace();
}
}
}
}
}
Server.java
package customChat;
import java.io.*;
import java.net.*;
import java.text.SimpleDateFormat;
import java.util.*;
public class Server {
private SimpleDateFormat sdf;
private int port;
private boolean keepGoing;
private String notif = " *** ";
public static ArrayList<ClientThread> al;
public Server(int port)
{
this.port = port;
sdf = new SimpleDateFormat("HH:mm:ss");
al = new ArrayList<ClientThread>();
}
public void start() {
keepGoing = true;
try
{
ServerSocket serverSocket = new ServerSocket(port);
while(keepGoing)
{
display("Server waiting for Clients on port " + port + ".");
Socket socket = serverSocket.accept();
if(!keepGoing)
break;
ClientThread t = new ClientThread(socket);
Thread t1 =new Thread(t);
System.out.println("Connection initiated by:"+t.access.getFrom());
Server.al.add(t);
t1.start();
}
/*try {
serverSocket.close();
for(int i = 0; i < Server.al.size(); ++i) {
ClientThread tc = Server.al.get(i);
try {
tc.sInput.close();
tc.sOutput.close();
tc.socket.close();
}
catch(IOException ioE) {
ioE.printStackTrace();
}
}
}
catch(Exception e)
{
display("Exception closing the server and clients: " + e);
}*/
}
catch (IOException e) {
String msg = sdf.format(new Date()) + " Exception on new ServerSocket: " + e + "\n";
display(msg);
}
}
/*protected void stop() {
keepGoing = false;
try {
new Socket("localhost", port);
}
catch(Exception e) {
}
}*/
// Display an event to the console
private void display(String msg) {
String time = sdf.format(new Date()) + " " + msg;
System.out.println(time);
}
public static void main(String[] args) {
// start server on port 1500 unless a PortNumber is specified
int portNumber = 1502;
// create a server object and start it
Server server = new Server(portNumber);
server.start();
}
}
ClientThread.java
package customChat;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Date;
/*class ListClient
{
public static ArrayList<ClientThread> al=new ArrayList<>();;
}*/
public class ClientThread implements Runnable {
Socket socket;
ObjectInputStream sInput;
ObjectOutputStream sOutput;
String date;
RemoteAccess access;
public RemoteAccess getAccess() {
return access;
}
public void setAccess(RemoteAccess access) {
this.access = access;
}
// Constructor
ClientThread(Socket socket) {
this.socket = socket;
System.out.println("Thread trying to create Object Input/Output Streams");
try
{
sOutput = new ObjectOutputStream(socket.getOutputStream());
sInput = new ObjectInputStream(socket.getInputStream());
System.out.println("CT input Stream :"+sInput);
access = (RemoteAccess) sInput.readObject();
System.out.println(access.getFrom() +"Joined the chat room");
}
catch (IOException e)
{
e.printStackTrace();
System.out.println("Exception creating new Input/output Streams: " + e);
return;
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
date = new Date().toString() + "\n";
}
/*private void close() {
try {
if(sOutput != null) sOutput.close();
}
catch(Exception e) {
e.printStackTrace();
}
try {
if(sInput != null) sInput.close();
}
catch(Exception e) {
e.printStackTrace();
};
try {
if(socket != null) socket.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
*/
#Override
public void run()
{
System.out.println("List size is :"+Server.al.size());
for(int i=0;i<Server.al.size();i++)
{
try {
System.out.println("Socket input Stream :"+Server.al.get(i).socket.getInputStream());
System.out.println("Socket :"+socket.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
if(Server.al.get(i).access.getFrom()==access.getTo())
{
System.out.println("I am in if part :"+Server.al.get(i).access.getFrom() +"compare to :"+access.getTo());
PairHandler t = null;
try {
t = new PairHandler(access.getTo(),Server.al.get(i).socket,Server.al.get(i).socket.getInputStream(),Server.al.get(i).socket.getOutputStream(),socket.getOutputStream(),socket.getInputStream(),socket);
} catch (IOException e) {
e.printStackTrace();
}
Thread t1 = new Thread(t);
System.out.println("Connection initiated by in CT:"+access.getFrom());
t1.start();
}
else{
System.out.println("I am in else in CT");
}
}
}
}
PairHandler.java
This is where i am using two client socket
package customChat;
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 PairHandler implements Runnable
{
long stbId;
Socket tvsocket;
ObjectInputStream tvsInput;
ObjectOutputStream tvsOutput;
Socket dtsocket;
ObjectInputStream dtsInput;
ObjectOutputStream dtsOutput;
PairHandler(long stbId,Socket tvsocket,Socket dtsocket)
{
this.stbId = stbId;
this.tvsocket = tvsocket;
this.dtsocket = dtsocket;
try
{
tvsOutput = new ObjectOutputStream(tvsocket.getOutputStream());
dtsOutput = new ObjectOutputStream(dtsocket.getOutputStream());
System.out.println("DT output Stream is :"+dtsOutput);
System.out.println("Tv outPut Stream is :"+tvsOutput);
System.out.println("RH input Stream :"+tvsocket.getInputStream());
tvsInput = new ObjectInputStream(tvsocket.getInputStream());
System.out.println("Tv input Stream is :"+tvsInput);
dtsInput = new ObjectInputStream(dtsocket.getInputStream());
System.out.println("DT input Stream is :"+dtsInput);
}
catch (IOException e)
{
e.printStackTrace();
System.out.println("Exception creating in Pair Handler new Input/output Streams: " + e);
return;
}
}
public PairHandler(long to, Socket socket, InputStream inputStream, OutputStream outputStream,
OutputStream outputStream2, InputStream inputStream2, Socket socket2) {
stbId = to;
tvsocket = socket;
dtsocket = socket2;
try{
tvsOutput = new ObjectOutputStream(outputStream);
dtsOutput = new ObjectOutputStream(outputStream2);
System.out.println("DT output Stream is :"+dtsOutput);
System.out.println("Tv input Stream is :"+socket.getInputStream());
System.out.println("DT input Stream is :"+socket2.getInputStream());
tvsInput = new ObjectInputStream(socket2.getInputStream());
System.out.println("Tv input Stream is 2 :"+tvsInput);
dtsInput = new ObjectInputStream(socket2.getInputStream());
System.out.println("DT input Stream is :"+dtsInput);
System.out.println("Tv input Stream is :"+tvsInput);
// TODO Auto-generated constructor stub
}
catch (IOException e)
{
System.out.println("Exception in PH");
e.printStackTrace();
}
}
#Override
public void run()
{
try
{
//dtsInput = new ObjectInputStream(dtsocket.getInputStream());
System.out.println("DT socket :"+dtsInput);
if(dtsInput!=null){
RemoteAccess dtMsg = (RemoteAccess) dtsInput.readObject();
if(dtMsg !=null){
// write to tvscoket
System.out.println("I am here in Pair Handler");
sendTOTv(dtMsg);
}
}
// tvsInput = new ObjectInputStream(tvsocket.getInputStream());
System.out.println("TV socket :"+tvsInput);
if(tvsInput!=null){
RemoteAccess tvmsg = (RemoteAccess) tvsInput.readObject();
if(tvmsg !=null){
// write to dtsocket
sendToDT(tvmsg);
}
}
}
catch (IOException e)
{
e.printStackTrace();
System.out.println("Exception found while msg");
}
catch(ClassNotFoundException e2) {
e2.printStackTrace();
}
}
private void sendToDT(RemoteAccess tvmsg) {
// TODO Auto-generated method stub
// if Client is still connected send the message to it
if(!dtsocket.isConnected())
{
closeDtSocket();
}
try {
dtsOutput.writeObject(tvmsg);
}
catch(IOException e) {
System.out.println("Failed to deliver msg");
}
}
private void closeDtSocket() {
try {
if(dtsOutput != null) dtsOutput.close();
}
catch(Exception e) {
e.printStackTrace();
}
try {
if(dtsInput != null) dtsInput.close();
}
catch(Exception e) {
e.printStackTrace();
};
try {
if(dtsocket != null) dtsocket.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
private void closeTvSocket() {
try {
if(tvsOutput != null) tvsOutput.close();
}
catch(Exception e) {
e.printStackTrace();
}
try {
if(tvsInput != null) tvsInput.close();
}
catch(Exception e) {
e.printStackTrace();
};
try {
if(tvsocket != null) tvsocket.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
private void sendTOTv(RemoteAccess dtMsg) {
// TODO Auto-generated method stub
if(!tvsocket.isConnected())
{
closeTvSocket();
}
try {
tvsOutput.writeObject(dtMsg);
}
catch(IOException e) {
System.out.println("Failed to deliver msg");
}
}
}
RemoteAccess.java
package customChat;
import java.io.File;
import java.io.Serializable;
class RemoteAccess implements Serializable {
private static final long serialVersionUID = 1L;
private long to;
private long from;
private File file;
private String msg;
private int x ;
private int y;
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
RemoteAccess(){
}
RemoteAccess(long to,long from)
{
this.to=to;
this.from=from;
}
RemoteAccess(long to,long from,File file)
{
this.to=to;
this.from=from;
this.file=file;
}
RemoteAccess(long to,long from,int x,int y)
{
this.to=to;
this.from=from;
this.x=x;
this.y=y;
}
RemoteAccess(long to,long from,String msg)
{
this.to=to;
this.from=from;
this.msg=msg;
}
public File getFile() {
return file;
}
public void setFile(File file) {
this.file = file;
}
public long getTo() {
return to;
}
public void setTo(long to) {
this.to = to;
}
public long getFrom() {
return from;
}
public void setFrom(long from) {
this.from = from;
}
}
I supposed you want to customize client1 and client2. So you should create a class for each one :
public class Client1 extends Socket {
public Client1() {
super();
}
//Add stuff to customize
}
public class Client2 extends Socket {
public Client2() {
super();
}
//Add stuff to customize
}
Then create your class that contains your two sockets :
public class ClientDialog {
private Client1 client1;
private Client2 client2;
public ClientDialog() {
client1 = new Client1();
client2 = new Client1();
}
//Dialog between client
}
Hello dear programmers ,
I am trying to make a tic tac toe game using android, my android application contains several activities, one of these activities can the allows client to send a message to the server asking if X user wants to challenge, if the user accepts the challenge the server messages me and we both move forward to another activity.
My server is running as a regular java code on my PC, this is my server code :
public class Server {
ServerSocket serverSocket;
ArrayList<ServerThread> allClients = new ArrayList<ServerThread>();
public static void main(String[] args) {
new Server();
}
public Server() {
// ServerSocket is only opened once !!!
try {
serverSocket = new ServerSocket(6000);
System.out.println("Waiting on port 6000...");
boolean connected = true;
// this method will block until a client will call me
while (connected) {
Socket singleClient = serverSocket.accept();
// add to the list
ServerThread myThread = new ServerThread(singleClient);
allClients.add(myThread);
myThread.start();
}
// here we also close the main server socket
serverSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
class ServerThread extends Thread {
Socket threadSocket;
String userName;
boolean isClientConnected;
InputStream input;
ObjectInputStream ois;
OutputStream output;
ObjectOutputStream oos; // ObjectOutputStream
public ServerThread(Socket s) {
threadSocket = s;
}
public void sendText(String text) {
try {
oos.writeObject(text);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void run() {
try {
input = threadSocket.getInputStream();
ois = new ObjectInputStream(input);
output = threadSocket.getOutputStream();
oos = new ObjectOutputStream(output);
userName = (String) ois.readObject();
isClientConnected = true;
System.out.println("User " + userName + " has connected");
while (isClientConnected) {
String singleText = (String) ois.readObject();
System.out.println(singleText);
for (ServerThread t : allClients)
t.sendText(singleText);
// oos.writeObject(singleText);
}
// close all resources (streams and sockets)
ois.close();
oos.close();
threadSocket.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
I use the communication between clients in only two activies, both activites contain the same connectUser() code :
public class MenuActivity extends Activity {
public static final String HOST = "10.0.2.2";
public static final int PORT = 6000;
static ConnectThread clientThread;
boolean isConnected;
static boolean isOnline = false;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_menu);
runOnUiThread(new Runnable() {
public void run() {
connectUser();
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void connectUser() {
clientThread = new ConnectThread();
clientThread.start();
}
class ConnectThread extends Thread {
InputStream input;
OutputStream output;
ObjectOutputStream oos;
Socket s;
public void sendText(String text) {
try {
oos.writeObject(text);
System.out.println(text);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void run() {
try {
s = new Socket(HOST, PORT);
output = s.getOutputStream();
oos = new ObjectOutputStream(output);
oos.writeObject(un);
isOnline = true;
isConnected = true;
new ListenThread(s).start();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class ListenThread extends Thread {
Socket s;
InputStream input;
ObjectInputStream ois;
public ListenThread(Socket s) {
this.s = s;
try {
input = s.getInputStream();
ois = new ObjectInputStream(input);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void run() {
while (isConnected) {
try {
final String inputMessage = (String) ois.readObject();
//do something with the message }
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
I use this code this code to send message to the server :
clientThread.sendText(user + " " + opponent + " play");
The problem is that when I create the connection at the first activity, then move to the second activity I create another connection , which means so far I am having two connections, same with other clients and then the server seems to return a timed out error.
My question is how to do a global client variable that is created once and can be used in each activity. I saw many suggestions like socket service or asyntask , but I need more direction and help
Thanks in advance.
Add a sub class of Application to your project and update application tag and add this class as android:name:
<application
android:name="com.your.app.MyApplication"
...
and then create a static reference to your Socket connection in MyApplication class:
private static Socket connection;
and then add a static method to access this object:
public static Socket getConnection() {
if( connection == null) {
// initialize connection object here
}
return connection;
}
Now you have a global object!
I have a somewhat simple server meaning that i am trying to learn different design patterns by making a server as object orientated as possible. Suprisingly so far i havnt had a single problem untill i created the method close().
apprently when a client closes his connection with the database the BufferReader still wants input and throws an execption saying that Java.net.socketExecption: socket closed
since i have alot of different classes i will only post the ones that are failing at the moment if you need additional information please do not hesitate to send me a comment. Also since i am trying to learn from this project please comment on my code aswell if you feel like it :)
Code (all of my code)
public class ServerConnectionManager {
private static ServerSocket server;
private static Socket connection;
private static ServerInformation ai = new ServerInformation();
private static boolean connected = false;
private static final int portNumber = 7070;
private static int backLog = 100;
/**
* This method launches the server (and the application)!
* #param args
*/
public static void main(String[] args){
startServer();
waitForConnection();
}
/**
*This method sets the serverSocket to portNumber and also adds the backLog.
*/
private static void startServer() {
try {
server = new ServerSocket(portNumber, backLog);
connected = true;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* This method waits for a connection aslong as the serverSocket is connected.
* When a new client connects it creates an Object of the connection and starts the individual procedure.
*/
private static void waitForConnection() {
while (connected) {
try {
connection = server.accept();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Connection c = new Connection(connection);
ai.addToConnectionList(c);
waitForConnection();
}
}
public void closeMe(Socket con) {
for (Connection conn : ai.getConnectionList()) {
if (conn.getConnection() == con) {
conn.close();
}
}
}
}
Connection
public class Connection{
private Socket connection;
public Connection(Socket connection){
this.connection = connection;
ServerListner cl = new ServerListner(Connection.this);
cl.start();
}
public Socket getConnection(){
return this.connection;
}
public void close() {
try {
connection.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
ServerListner
public class ServerListner extends Thread {
private Socket connection;
private BufferedReader br;
private ChatPerson person;
private Connection con;
private ServerInformation ai = new ServerInformation();
private ServerConnectionManager scm = new ServerConnectionManager();
private ServerSender sender = new ServerSender();
public ServerListner(Connection con){
this.con = con;
connection = con.getConnection();
try {
br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public Socket getConnection(){
return this.connection;
}
public void run(){
while (con.getConnection().isConnected()) {
String inString;
try {
while ((inString = br.readLine()) != null) {
processInput(inString);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void processInput(String input){
if (input.equalsIgnoreCase("Connect")) {
sender.sendMessageToConnection(this.connection, "Accepted");
}
if (input.equalsIgnoreCase("UserInformation")) {
try {
String username = br.readLine();
person = new ChatPerson(username, connection);
ai.add(person);
System.out.println(ai.getList());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (input.equalsIgnoreCase("SearchByCon")) {
String name = ai.searchByConnection(connection);
System.out.println(name);
}
if (input.equals("Disconnect")) {
scm.closeMe(connection);
}
}
}
** Server Sender**
public class ServerSender {
private PrintWriter pw;
private ServerInformation ai = new ServerInformation();
public void addToList(){
}
public void sendToAll(String message){
for (Connection c : ai.getConnectionList()) {
try {
pw = new PrintWriter(c.getConnection().getOutputStream());
pw.print(message);
pw.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
*
* #param con
* #param message
*/
/*
* Note - Denne metode gør også at jeg kan hviske til folk!:)
*/
public void sendMessageToConnection(Socket con, String message){
try {
PrintWriter print = new PrintWriter(con.getOutputStream());
print.println(message);
print.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
** Server Information**
public class ServerInformation {
private ArrayList<Connection> connectedClients = new ArrayList<Connection>();
private ArrayList<ChatPerson> list = new ArrayList<ChatPerson>();
public ArrayList<Connection> getConnectionList(){
return connectedClients;
}
public void addToConnectionList(Connection con){
connectedClients.add(con);
}
public String searchByConnection(Socket myConnection){
for (ChatPerson p : list) {
if (p.getConnection() == myConnection) {
return p.getName();
}
}
/*
* If none found!
*/
return null;
}
public void add(ChatPerson p){
list.add(p);
}
public void removeByName(String name){
for (ChatPerson p : list) {
if (p.getName().equalsIgnoreCase(name)) {
list.remove(p);
}
}
}
public String searchList(String name){
for (ChatPerson p : list) {
if (p.getName().equalsIgnoreCase(name)) {
return p.getName();
}
}
return null;
}
public ArrayList<ChatPerson>getList(){
return list;
}
}
** ChatPerson**
public class ChatPerson {
private String chatName;
private Socket connection;
/*
* This is for furture development
* private Integer adminLevel;
*/
public ChatPerson(String name, Socket connection){
this.chatName = name;
this.connection = connection;
}
public void setName(String name){
this.chatName = name;
}
public String getName(){
return chatName;
}
public String toString(){
return "Username: "+chatName;
}
public Socket getConnection(){
return connection;
}
}
I have tried the following thing(s):
try {
String inString;
while ((inString = br.readLine()) != null) {
if (inString.equalsIgnoreCase("Disconnect")) {
System.out.println(inString);
break;
}else {
processInput(inString);
}
}
scm.closeMe(connection);
This did not work still gave me the same execption.
while (con.getConnection().isConnected()) {
String inString;
try {
while ((inString = br.readLine()) != null) {
processInput(inString);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Having both these loops is meaningless. readLine() will return null as soon as EOS is reached, at which point you should close the socket and exit the loop. In any case isConnected() doesn't tell you anything about the state of the connection, only about which APIs you have called on your Socket which is the endpoint of it. Lose the outer loop.
The documentation on Socket says
Any thread currently blocked in an I/O operation upon this socket will throw a SocketException.
You may want to break out of your readline() loop and close the connection outside of this.