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.
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.
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!
First i run serveur_final.java,creating thread for clients,getting login and password from client and in the second thread verify them in database and after sending "ok" to client and initialize communication
public class Serveur_final {
private ServerSocket sock_serv=null;
private Socket client_entrant=null;
private static Vector<String> nom_client=null;
private static Vector<connect_serveur> list_client=null;
private int port=1991;
public Serveur_final() throws IOException{
initialisation();
}
public void initialisation() throws IOException {
sock_serv=new ServerSocket(port);
System.out.println("ecoute au"+port);
list_client=new Vector<connect_serveur>();
nom_client=new Vector<String>();
while(true){
client_entrant=sock_serv.accept();
connect_serveur con=new connect_serveur(client_entrant);
list_client.add(con) ;
}
}
public static void ajouter_list(String nom_cli){
nom_client.add(nom_cli);
diffusion_list(nom_client);
}
public static void supprimer_nom_client(String con){
for(String nom: nom_client){
if(nom.equals(con)){
nom_client.remove(nom);
}
}
}
public static void supprimer_client(connect_serveur con){
for(connect_serveur nom: list_client){
if(nom.equals(con)){
list_client.remove(nom);}
}
}
public static Vector<connect_serveur> getList_client(){
return list_client;
}
public static void diffusion_list(Vector<String> client) {
for(connect_serveur cl: list_client){
for(int i=0;i<client.size();i++){
cl.diffuser(nom_client.get(i));
}
}
}
public static void diffusion_message(String client,String message) {
for(connect_serveur cl: list_client){
/*for(int i=0;i<nom_client.size();i++){*/
cl.getThead_client().getEnvoi_msg().diffusion(client, message);
/*}*/
}
}
public static void deconnection(String pseudo) {
for(connect_serveur cl: list_client){
if(cl.getPseudo().equals(pseudo)){
list_client.remove(cl);
}
for(int i=0;i<nom_client.size();i++){
if(pseudo.equals(nom_client.get(i))){
nom_client.remove(i);
}
}
}
}
}
/
///class connect-serveur
public class connect_serveur extends Thread {
private Socket client;
private BufferedReader reception;
private static PrintWriter envoi;
private String pseudo,passwd;
/* private static Vector<String> list_nom_client;*/
initialisation_communication thread_client;
private boolean verif=false, autorisation=false;
public connect_serveur(Socket client_entrant) throws IOException {
this.client=client_entrant;
envoi=new PrintWriter(client.getOutputStream());
reception=new BufferedReader(new InputStreamReader(client.getInputStream()));
pseudo=reception.readLine();
passwd=reception.readLine();
verif=verifier_info(pseudo, passwd);
setPseudo(pseudo);
start();
}
#Override
public void run() {
try {
if(!verif){
envoi.println("bye4");
envoi.flush();
Serveur_final.supprimer_client(this);
reception.close();
envoi.close();
client.close();
Serveur_final.deconnection(pseudo);
}
envoi.println("ok");
envoi.flush();
Serveur_final.ajouter_list(pseudo);
thread_client=new initialisation_communication(pseudo, envoi,reception);
setThead_client(thread_client);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void setPseudo(String pseudo2) {
this.pseudo=pseudo2;
}
public String getPseudo() {
return this.pseudo;
}
public initialisation_communication getThead_client(){
return thread_client;
}
public void setThead_client(initialisation_communication com ){
thread_client=com;
}
/*public static void diffuser_list(Vector<String>client){
list_nom_client=client;
for(int i=0;i<list_nom_client.size();i++){
diffuser(list_nom_client.get(i));
Serveur_final.diffusion_list();
}
}*/
public static void diffuser(String client) {
System.out.println("en diffusion");
envoi.println("0>>:"+client);
envoi.flush();
}
boolean verifier_info(String pseudo, String passwd) {
autorisation=connexion_bdd.getInstance().verification_log(pseudo, passwd);
System.out.println("AUTORISER"+autorisation);
if(autorisation)
{
envoi.println("ok");
envoi.flush();
System.out.println("adding user");
}
else {
envoi.println("no");
envoi.flush();
}
return autorisation;
}
}
//initialisation-comm class
public class initialisation_communication extends Thread {
private String pseudo;
private BufferedReader reception;
private PrintWriter envoi;
private envoyer_message envoi_msg;
private recevoir_message recoi_msg;
public initialisation_communication(String pseudo,PrintWriter envoi,BufferedReader reception) {
// TODO Auto-generated constructor stub
this.envoi=envoi;
this.reception=reception;
this.pseudo=pseudo;
start();
}
#Override
public void run() {
/*envoi=new PrintWriter(socket_client.getOutputStream());
BufferedReader reception = new BufferedReader(new InputStreamReader(socket_client.getInputStream()));*/
System.out.println("initialiser");
envoi_msg=new envoyer_message(pseudo,envoi,reception);
recoi_msg=new recevoir_message(reception);
setEnvoi_msg(envoi_msg);
}
public envoyer_message getEnvoi_msg(){
return envoi_msg;
}
public void setEnvoi_msg(envoyer_message com ){
this.envoi_msg=com;
}
}
//envoyer_msg class:from which i'm getting errors
public class envoyer_message extends Thread {
private PrintWriter emettre;
private BufferedReader reception;
private String pseudo;
public envoyer_message(String pseudo, PrintWriter envoi, BufferedReader reception) {
this.emettre=envoi;
this.reception=reception;
this.pseudo=pseudo;
System.out.println("dans envoyer dja");
start();
}
public void run(){
String message;
emettre.println("bien connectee");
try {
while (true) {
message = reception.readLine();
if(message=="!!>>fin<<!!"){
Serveur_final.deconnection(pseudo);
}
Serveur_final.diffusion_message(pseudo, message);
} // end of while
} // try
catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
public void diffusion(String pseudo2, String message) {
emettre.println(">>:"+pseudo2+"dit :"+message);
}
}
and finally my client
public class client_chat {
private Socket socket_client;
private String connected="",passwd,login,adress_server="localhost";
private int Port=1991;
private BufferedReader entrer=null;
private PrintWriter sortie=null;
private static client_chat client;
private boolean connecte=false;
private BufferedReader clavier ;
private String message;
private boolean fermer;
public client_chat(){
try {
this.socket_client=new Socket(adress_server,Port);
connecte=getConnection("nao", "nao");
init(connecte);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.getMessage();
}
}
public static client_chat getIntance(){
if(client==null){
client=new client_chat();
}
return client;
}
public boolean getConnection(String pseudo,String passwd){
this.login=pseudo;
this.passwd=passwd;
if(socket_client!=null){
try {
entrer=new BufferedReader(new InputStreamReader(socket_client.getInputStream()));
sortie=new PrintWriter(socket_client.getOutputStream());
sortie.println(pseudo);
sortie.flush();
sortie.println(passwd);
sortie.flush();
connected=entrer.readLine();
System.out.println(connected);
if(connected=="ok"){
connecte=true;
System.out.println(connected);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return connecte;
}
public void init(Boolean con) throws IOException{
if(con ){
new ThreadLecture().start();
while(!fermer){
clavier=new BufferedReader(new InputStreamReader(System.in));
sortie.println(clavier.readLine());
}
entrer.close();
sortie.close();
socket_client.close();
}
}
public void setLogin(String ps){
this.login=ps;
}
public String getLogin(){
return this.login;
}
public void setPasswd(String ps){
this.passwd=ps;
}
public String getPasswd(){
return this.passwd;
}
class ThreadLecture extends Thread{
public void run() {
try {
System.out.println("dans runcli");
while(true){
message=entrer.readLine();
System.out.println(message);
if(message.indexOf("bye4")!=-1 ||message.indexOf ("!!>>fin<<!!")!=-1)
break;
enter code here
}
fermer=true;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
error message after running client_chat.java
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:168)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
at java.io.InputStreamReader.read(InputStreamReader.java:167)
at java.io.BufferedReader.fill(BufferedReader.java:136)
at java.io.BufferedReader.readLine(BufferedReader.java:299)
at java.io.BufferedReader.readLine(BufferedReader.java:362)
at modeles.envoyer_message.run(envoyer_message.java:30)
sorry for my english, I need your help please!
I have tried all the tips
"All the tips" say the same thing, or they should. You have written to a connection that had already been closed by the other end. An application protocol error.
There isn't nearly enough EOS-checking in your code either. For example you are just assuming you receive both the username and the password.
I don't know if this will fix this, but i noticed your check:
if(message=="!!>>fin<<!!"){
in envoyer_msg.run() is wrong.
message is a String, string comparison is done by equals()/compareTo().
Cheers
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.