Stream Corrupted Exception - java

I'm writing a client/server program using sockets. The client first sends the file name and the server reads the file from hard disk and sends back to the client through socket. Finally the client writes the content into a file. When I run the code a java.io.StreamCorruptedException: invalid stream header error is returned.
Client code:
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ClientSocket {
private static final String SERVER_IP = "10.8.17.218";
private static final int SERVER_PORT = 5000;
String fileName;
String ip;
Socket socket;
Message msg=null,message=null;
ObjectInputStream in = null;
ObjectOutputStream out = null;
ObjectOutputStream toFile=null;
File destFile;
public ClientSocket(String ipi,String fname){
fileName = fname;
ip=ipi;
msg=new Message(fileName);
destFile=new File("C:\\DestinationDirectory",fileName);
try {
socket = new Socket(SERVER_IP, SERVER_PORT);
System.out.println("Connected to server!");
} catch (Exception ex) {
System.out.println("Error connecting to server: " + ex.getMessage());
}
while(true){
try {
if (out == null) {
out = new ObjectOutputStream(socket.getOutputStream());
}
out.writeObject(msg);
out.flush();
//get the reply from the server
if (in == null) {
in = new ObjectInputStream(socket.getInputStream());
}
message = (Message) in.readObject();
//System.out.println("Server said: " + message.getMessage());
} catch (Exception ex) {
System.out.println("Error: " + ex);
}
try {
toFile = new ObjectOutputStream(new FileOutputStream(destFile));
toFile.writeObject(message);
System.out.println(message.getMessage());
} catch (IOException ex) {
Logger.getLogger(ClientSocket.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public static void main(String[] args) {
ClientSocket cs= new ClientSocket("10.8.17.218","build.sql");
}
}
Server code:
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerFile {
private static final int PORT = 5000;
public static void main(String[] args) {
ServerSocket serverSocket = null;
Message message=null,toOut=null;
try {
//Creates a new server socket with the given port number
serverSocket = new ServerSocket(PORT);
} catch (IOException ex) {
System.out.println("Error occured while creating the server socket");
return;
}
Socket socket = null;
try {
//Waits untill a connection is made, and returns that socket
socket = serverSocket.accept();
} catch (IOException ex) {
System.out.println("Error occured while accepting the socket");
return;
}
//Now we have established the a connection with the client
System.out.println("Connection created, client IP: " + socket.getInetAddress());
ObjectInputStream in = null,fromFile=null;
ObjectOutputStream out = null,tempOut=null;
File sourceFile;
FileInputStream from=null;
BufferedInputStream bis;
String name=null;
while(true){
try {
if (in == null) {
in = new ObjectInputStream(socket.getInputStream());
}
message= (Message) in.readObject();
System.out.println("Client said: " + message.getMessage());
name=message.getMessage();
sourceFile=new File("D:\\temp\\",name);
name="D:\\temp\\"+name;
System.out.println(name);
from=new FileInputStream("D:/temp/build.sql");
bis=new BufferedInputStream(from);
fromFile=new ObjectInputStream(bis);
toOut=(Message) fromFile.readObject();
//Send a reply to the client
if (out == null) {
out = new ObjectOutputStream(socket.getOutputStream());
}
out.writeObject(toOut);
out.flush();
} catch (Exception ex) {
System.out.println("Error: " + ex);
}
}
}
}

You're creating a new ObjectInputStream per transaction in the server, yet you're using a single ObjectOutputStream in the client. You should use exactly one of each at both ends for the life of the socket.

Related

Why the socket is always close when i send the data in java TCP

server class :
the program is about to receive data from client and then reply. the server is okay..., but the problem is when the server send the reply to the client. the client always says 'the socket is close'. i try to delete secket close statement but the result is same.., the output says that 'the socket is close'. so please help me to solve this problem...
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;
public class Nomor3Server {
public static final int SERVICE_PORT = 2020;
public static void main(String[] args) {
try {
ServerSocket server = new ServerSocket(SERVICE_PORT);
System.out.println("DAytime service started");
for (;;) {
Socket nextClient = server.accept();
BufferedReader pesan = new BufferedReader(new InputStreamReader(nextClient.getInputStream()));
String messageIn = pesan.readLine();
System.out.println("Received request from "
+ nextClient.getInetAddress() + " : "
+ nextClient.getPort()
+ "\nIsi Pesan : " + messageIn);
String messageOut = "انا لا ادر";
switch (messageIn) {
case "saya":
messageOut = "أنا";
break;
case "kamu":
messageOut = "أنت";
break;
default:
break;
}
OutputStream out = nextClient.getOutputStream();
PrintStream pout = new PrintStream(out);
pout.print(messageOut);
out.flush();
out.close();
System.out.println("Message sent");
//nextClient.close();
}
} catch (BindException e) {
System.err.println("Server Already Running on port : " + SERVICE_PORT);
} catch (IOException ioe) {
System.err.println("error : " + ioe);
}
}
}
client class :
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
public class Nomor3Client {
public static final int SERVICE_PORT = 2020;
public static void main(String[] args) {
try {
String hostname = "localhost";
System.out.println("Connection Established");
//for (;;) {
System.out.println("Enter Your Message : ");
BufferedReader read = new BufferedReader(new InputStreamReader(System.in));
String pesan = read.readLine();
Socket daytime = new Socket(hostname, SERVICE_PORT);
if (pesan.equals("exit")) {
System.exit(0);
} else {
daytime.setSoTimeout(2000);
OutputStream out = daytime.getOutputStream();
PrintStream pout = new PrintStream(out);
pout.print(pesan);
out.flush();
out.close();
BufferedReader messageIn = new BufferedReader(new InputStreamReader(daytime.getInputStream()));
System.out.println("Respond : " + messageIn.readLine());
System.out.println("diterima");
}
daytime.close();
//}
} catch (IOException e) {
System.err.println("Error : " + e);
}
}
}
OutputStream out = daytime.getOutputStream();
PrintStream pout = new PrintStream(out);
pout.print(pesan);
out.flush();
out.close();
https://docs.oracle.com/javase/7/docs/api/java/net/Socket.html#getOutputStream()
Closing the returned OutputStream will close the associated socket.
Socket get closed in such situations:
when you close the socket,
when you close the input or the output socket stream,
when you close the object, which is directly or indirectly wrapping the input or the output socket stream, e.g. BufferedReader or Scanner.
Server Class
OutputStream out = nextClient.getOutputStream();
PrintStream pout = new PrintStream(out);
pout.print(messageOut);
out.flush();
out.close(); //Don't close this
Client Code :
OutputStream out = daytime.getOutputStream();
PrintStream pout = new PrintStream(out);
pout.print(pesan);
out.flush();
out.close(); //Don't close this

Java socket connection receiving and sending String and Object

I've created a client, a server and an object called CcyData. When the client connects to the server I would like the server the send a "Welcome message" like "Hello, you are client# " + clientNumber. as a String and then send an object CcyData. I've managed to get the sending of the CcyData object to work but when I try to read in the "Welcome message" with
input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println("Welcome message from server: "+ input.readLine());
the client stops working, nothing happens. No error message. Below is my code. How can I solve this?
Server.
package net.something;
import java.io.IOException;
import java.net.ServerSocket;
public class SocketServer {
private ServerSocket serverSocket = null;
private int clientNumber = 0;
public SocketServer() {
}
public void listenSocket () {
int clientNumber = 0;
try{
serverSocket = new ServerSocket(9090);
System.out.println("Server started on port 9090");
} catch(IOException e) {
e.printStackTrace();
}
while (true) {
ClientSocket clientSocket;
try{
clientSocket = new ClientSocket(serverSocket.accept(), serverSocket, clientNumber++);
Thread thread = new Thread(clientSocket);
thread.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Class ClientSocket
package net.something;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class ClientSocket implements Runnable {
private Socket clientSocket;
private ServerSocket serverSocket;
private int clientNumber;
public ClientSocket(Socket clientSocket, ServerSocket serverSocket, int clientNumber) {
this.clientSocket = clientSocket;
this.serverSocket = serverSocket;
this.clientNumber = clientNumber;
System.out.println("New connection with client# " + clientNumber + " at " + clientSocket);
}
public void run() {
PrintWriter out;
ObjectOutputStream outObjectStream;
try {
out = new PrintWriter(clientSocket.getOutputStream());
out.println("Hello, you are client# " + clientNumber);
outObjectStream = new ObjectOutputStream(clientSocket.getOutputStream());
CcyData ccyData = new CcyData("EUR", 9.56);
System.out.println("CcyData: " + ccyData.getCcy() + " " + ccyData.getFxRate());
outObjectStream.writeObject(ccyData);
} catch (IOException e) {
e.printStackTrace();
}
}
public void finalize() {
try{
serverSocket.close();
System.out.println("Server socket closed");
} catch (IOException e) {
e.printStackTrace();
}
}
}
Client
package net.something;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.net.Socket;
public class SocketClient {
private Socket socket = null;
private BufferedReader input;
private ObjectInputStream inObjectStream = null;
public SocketClient() {
}
public void connectToServer() {
try{
socket = new Socket("127.0.0.1", 9090);
input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println("Welcome message from server: "+ input.readLine());
inObjectStream = new ObjectInputStream(socket.getInputStream());
CcyData ccyData = (CcyData) inObjectStream.readObject();
System.out.println(ccyData.getCcy() + " " + ccyData.getFxRate());
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
finalize is only called when the JVM garbage collector decides that there are no more references to your thread and disposes it. Thus, you cannot ensure that finalize will be called when your thread has reached the end of its run() method. Try closing the socket in the run method instead!

How to accept socket while reading a DataInputStream? [duplicate]

How do you handle multiple client to connect to one server? I have this LogServer.java
import javax.net.ssl.*;
import javax.net.*;
import java.io.*;
import java.net.*;
public class LogServer {
private static final int PORT_NUM = 5000;
public static void main(String args[]) {
ServerSocketFactory serverSocketFactory =
ServerSocketFactory.getDefault();
ServerSocket serverSocket = null;
try {
serverSocket =
serverSocketFactory.createServerSocket(PORT_NUM);
} catch (IOException ignored) {
System.err.println("Unable to create server");
System.exit(-1);
}
System.out.printf("LogServer running on port: %s%n", PORT_NUM);
while (true) {
Socket socket = null;
try {
socket = serverSocket.accept();
InputStream is = socket.getInputStream();
BufferedReader br = new BufferedReader(
new InputStreamReader(is, "US-ASCII"));
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException exception) {
// Just handle next request.
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException ignored) {
}
}
}
}
}
}
and an embedded applet with part of the code like this e.g
import java.io.*;
import java.util.logging.*;
public class LogTest
{
private static Logger logger = Logger.getAnonymousLogger();
public static void main(String argv[]) throws IOException
{
Handler handler = new SocketHandler("localhost", 5000);
logger.addHandler(handler);
logger.log(Level.SEVERE, "Hello, World");
logger.log(Level.SEVERE, "Welcome Home");
logger.log(Level.SEVERE, "Hello, World");
logger.log(Level.SEVERE, "Welcome Home");
}
}
now the question is if I run "java LogServer" on the server, it will open the application and waiting for input stream and if I open my site, it will start streaming the log. But if I open one more using other computer/network, the second site does not log the stream. seems like it's because the first one still bind to port 5000.
How do I handle this?
How does socket actually work with multiple client / one server?
For every client you need to start separate thread. Example:
public class ThreadedEchoServer {
static final int PORT = 1978;
public static void main(String args[]) {
ServerSocket serverSocket = null;
Socket socket = null;
try {
serverSocket = new ServerSocket(PORT);
} catch (IOException e) {
e.printStackTrace();
}
while (true) {
try {
socket = serverSocket.accept();
} catch (IOException e) {
System.out.println("I/O error: " + e);
}
// new thread for a client
new EchoThread(socket).start();
}
}
}
and
public class EchoThread extends Thread {
protected Socket socket;
public EchoThread(Socket clientSocket) {
this.socket = clientSocket;
}
public void run() {
InputStream inp = null;
BufferedReader brinp = null;
DataOutputStream out = null;
try {
inp = socket.getInputStream();
brinp = new BufferedReader(new InputStreamReader(inp));
out = new DataOutputStream(socket.getOutputStream());
} catch (IOException e) {
return;
}
String line;
while (true) {
try {
line = brinp.readLine();
if ((line == null) || line.equalsIgnoreCase("QUIT")) {
socket.close();
return;
} else {
out.writeBytes(line + "\n\r");
out.flush();
}
} catch (IOException e) {
e.printStackTrace();
return;
}
}
}
}
You can also go with more advanced solution, that uses NIO selectors, so you will not have to create thread for every client, but that's a bit more complicated.
This is the echo server handling multiple clients... Runs fine and good using Threads
// echo server
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class Server_X_Client {
public static void main(String args[]){
Socket s=null;
ServerSocket ss2=null;
System.out.println("Server Listening......");
try{
ss2 = new ServerSocket(4445); // can also use static final PORT_NUM , when defined
}
catch(IOException e){
e.printStackTrace();
System.out.println("Server error");
}
while(true){
try{
s= ss2.accept();
System.out.println("connection Established");
ServerThread st=new ServerThread(s);
st.start();
}
catch(Exception e){
e.printStackTrace();
System.out.println("Connection Error");
}
}
}
}
class ServerThread extends Thread{
String line=null;
BufferedReader is = null;
PrintWriter os=null;
Socket s=null;
public ServerThread(Socket s){
this.s=s;
}
public void run() {
try{
is= new BufferedReader(new InputStreamReader(s.getInputStream()));
os=new PrintWriter(s.getOutputStream());
}catch(IOException e){
System.out.println("IO error in server thread");
}
try {
line=is.readLine();
while(line.compareTo("QUIT")!=0){
os.println(line);
os.flush();
System.out.println("Response to Client : "+line);
line=is.readLine();
}
} catch (IOException e) {
line=this.getName(); //reused String line for getting thread name
System.out.println("IO Error/ Client "+line+" terminated abruptly");
}
catch(NullPointerException e){
line=this.getName(); //reused String line for getting thread name
System.out.println("Client "+line+" Closed");
}
finally{
try{
System.out.println("Connection Closing..");
if (is!=null){
is.close();
System.out.println(" Socket Input Stream Closed");
}
if(os!=null){
os.close();
System.out.println("Socket Out Closed");
}
if (s!=null){
s.close();
System.out.println("Socket Closed");
}
}
catch(IOException ie){
System.out.println("Socket Close Error");
}
}//end finally
}
}
Also here is the code for the client.. Just execute this code for as many times as you want to create multiple client..
// A simple Client Server Protocol .. Client for Echo Server
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
public class NetworkClient {
public static void main(String args[]) throws IOException{
InetAddress address=InetAddress.getLocalHost();
Socket s1=null;
String line=null;
BufferedReader br=null;
BufferedReader is=null;
PrintWriter os=null;
try {
s1=new Socket(address, 4445); // You can use static final constant PORT_NUM
br= new BufferedReader(new InputStreamReader(System.in));
is=new BufferedReader(new InputStreamReader(s1.getInputStream()));
os= new PrintWriter(s1.getOutputStream());
}
catch (IOException e){
e.printStackTrace();
System.err.print("IO Exception");
}
System.out.println("Client Address : "+address);
System.out.println("Enter Data to echo Server ( Enter QUIT to end):");
String response=null;
try{
line=br.readLine();
while(line.compareTo("QUIT")!=0){
os.println(line);
os.flush();
response=is.readLine();
System.out.println("Server Response : "+response);
line=br.readLine();
}
}
catch(IOException e){
e.printStackTrace();
System.out.println("Socket read Error");
}
finally{
is.close();os.close();br.close();s1.close();
System.out.println("Connection Closed");
}
}
}
I guess the problem is that you need to start a separate thread for each connection and call serverSocket.accept() in a loop to accept more than one connection.
It is not a problem to have more than one connection on the same port.
See O'Reilly "Java Cookbook", Ian Darwin - recipe 17.4 Handling Multiple Clients.
Pay attention that accept() is not thread safe, so the call is wrapped within synchronized.
64: synchronized(servSock) {
65: clientSocket = servSock.accept();
66: }
Here is code for Multiple Client to one Server Working Fine ..
Give it a try :)
Server.java:
import java.io.DataInputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
class Multi extends Thread{
private Socket s=null;
DataInputStream infromClient;
Multi() throws IOException{
}
Multi(Socket s) throws IOException{
this.s=s;
infromClient = new DataInputStream(s.getInputStream());
}
public void run(){
String SQL=new String();
try {
SQL = infromClient.readUTF();
} catch (IOException ex) {
Logger.getLogger(Multi.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("Query: " + SQL);
try {
System.out.println("Socket Closing");
s.close();
} catch (IOException ex) {
Logger.getLogger(Multi.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public class Server {
public static void main(String args[]) throws IOException,
InterruptedException{
while(true){
ServerSocket ss=new ServerSocket(11111);
System.out.println("Server is Awaiting");
Socket s=ss.accept();
Multi t=new Multi(s);
t.start();
Thread.sleep(2000);
ss.close();
}
}
}
Client1.java:
import java.io.DataOutputStream;
import java.io.ObjectInputStream;
import java.net.Socket;
public class client1 {
public static void main(String[] arg) {
try {
Socket socketConnection = new Socket("127.0.0.1", 11111);
//QUERY PASSING
DataOutputStream outToServer = new DataOutputStream(socketConnection.getOutputStream());
String SQL="I am client 1";
outToServer.writeUTF(SQL);
} catch (Exception e) {System.out.println(e); }
}
}
Client2.java
import java.io.DataOutputStream;
import java.net.Socket;
public class client2 {
public static void main(String[] arg) {
try {
Socket socketConnection = new Socket("127.0.0.1", 11111);
//QUERY PASSING
DataOutputStream outToServer = new DataOutputStream(socketConnection.getOutputStream());
String SQL="I am Client 2";
outToServer.writeUTF(SQL);
} catch (Exception e) {System.out.println(e); }
}
}

Why my Java server close sockets?

I have server and client.
My server acepts all connections and returns to client string.
But when I try to send more lines its crashed with
java.net.SocketException: Socket is closed
at java.net.Socket.getOutputStream(Unknown Source)
at server.ServerCore.hiMsg(ServerCore.java:67)
at server.ServerCore.run(ServerCore.java:49)
Here is it my Server Code :
package server;
import java.io.File;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.*;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* #author pisio
*/
public class ServerCore extends Thread {
private LoadSettings loadSettings = LoadSettings.Init();
private int port = loadSettings.getConfigInt("port");
private int max_connections = loadSettings.getConfigInt("max_connections");
private String ipServer = loadSettings.getConfig("ipServer");
private ServerSocket socket;
private Socket connection;
private boolean serverRuning = false;
private int connectedUsers = 0;
private Vector connVector = new Vector();
#Override
public void run() {
try {
socket = new ServerSocket(port, max_connections);
System.out.println("+++\t Server was started at address:" + socket.getLocalSocketAddress() + " with posible max users " + max_connections);
serverRuning = true;
while (serverRuning) {
if (connectedUsers <= max_connections) {
connection = socket.accept();
connection.setKeepAlive(serverRuning);
connVector.add(connection);
connectedUsers = connVector.size();
hiMsg();
hiMsg();
hiMsg();
}
System.out.println("+++\t Last User:" + connVector.get(connVector.size() - 1).toString());
}
} catch (IOException ex) {
// Logger.getLogger(ServerCore.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void hiMsg() {
try {
Socket c = (Socket) connVector.get(connVector.size() - 1);
PrintWriter out = new PrintWriter(new OutputStreamWriter(c.getOutputStream()));
out.write("Hi user ! Im server ! Your master ! Blow me down\nping: ? PONG ?");
out.close();
} catch (IOException ex) {
Logger.getLogger(ServerCore.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void stopServer() {
statusServer();
serverRuning = false;
try {
socket.close();
} catch (IOException ex) {
//Logger.getLogger(ServerCore.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("+++++\t SERVER WAS STOPED !");
// System.exit(port);
}
public void statusServer() {
if (serverRuning) {
System.out.println("Server running at port:" + port + " with connected users :" + connectedUsers + "/" + max_connections);
} else {
System.out.println("Server IS NOT RUNNING!");
}
}
}
And Here is it my client code :
package meetingsclient;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.String;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ServerConnect {
private static ServerConnect sc = null;
private Socket socket = null;
private ServerConnect() {
try {
socket = new Socket("localhost", 8080);
sendHiMsg();
} catch (Exception ex) {
Logger.getLogger(ServerConnect.class.getName()).log(Level.SEVERE, null, ex);
}
}
private void sendHiMsg() throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println("Input:" + in.readLine());
}
public static ServerConnect Init() {
if (sc == null) {
sc = new ServerConnect();
}
return ServerConnect.sc;
}
}
I readed this topic : Socket Exception: socket is closed but this dotn helped me.
// Sorry for the links , but I cant understand how properly to format my code here.
From the javadoc of getOutputStream() in Socket:
Closing the returned OutputStream will close the associated socket.
Also, closing a PrintWriter (and all other Printers/Writers) close their underlying streams as well. So, you are closing your OutputStream by closing the PrintWriter (in hiMsg()) and then trying to write to the socket, which was closed.
To fix the problem, don't close the PrintWriter. Garbage collection will take care of it for you! But do close the socket when you are done with it.

socket programming multiple client to one server

How do you handle multiple client to connect to one server? I have this LogServer.java
import javax.net.ssl.*;
import javax.net.*;
import java.io.*;
import java.net.*;
public class LogServer {
private static final int PORT_NUM = 5000;
public static void main(String args[]) {
ServerSocketFactory serverSocketFactory =
ServerSocketFactory.getDefault();
ServerSocket serverSocket = null;
try {
serverSocket =
serverSocketFactory.createServerSocket(PORT_NUM);
} catch (IOException ignored) {
System.err.println("Unable to create server");
System.exit(-1);
}
System.out.printf("LogServer running on port: %s%n", PORT_NUM);
while (true) {
Socket socket = null;
try {
socket = serverSocket.accept();
InputStream is = socket.getInputStream();
BufferedReader br = new BufferedReader(
new InputStreamReader(is, "US-ASCII"));
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException exception) {
// Just handle next request.
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException ignored) {
}
}
}
}
}
}
and an embedded applet with part of the code like this e.g
import java.io.*;
import java.util.logging.*;
public class LogTest
{
private static Logger logger = Logger.getAnonymousLogger();
public static void main(String argv[]) throws IOException
{
Handler handler = new SocketHandler("localhost", 5000);
logger.addHandler(handler);
logger.log(Level.SEVERE, "Hello, World");
logger.log(Level.SEVERE, "Welcome Home");
logger.log(Level.SEVERE, "Hello, World");
logger.log(Level.SEVERE, "Welcome Home");
}
}
now the question is if I run "java LogServer" on the server, it will open the application and waiting for input stream and if I open my site, it will start streaming the log. But if I open one more using other computer/network, the second site does not log the stream. seems like it's because the first one still bind to port 5000.
How do I handle this?
How does socket actually work with multiple client / one server?
For every client you need to start separate thread. Example:
public class ThreadedEchoServer {
static final int PORT = 1978;
public static void main(String args[]) {
ServerSocket serverSocket = null;
Socket socket = null;
try {
serverSocket = new ServerSocket(PORT);
} catch (IOException e) {
e.printStackTrace();
}
while (true) {
try {
socket = serverSocket.accept();
} catch (IOException e) {
System.out.println("I/O error: " + e);
}
// new thread for a client
new EchoThread(socket).start();
}
}
}
and
public class EchoThread extends Thread {
protected Socket socket;
public EchoThread(Socket clientSocket) {
this.socket = clientSocket;
}
public void run() {
InputStream inp = null;
BufferedReader brinp = null;
DataOutputStream out = null;
try {
inp = socket.getInputStream();
brinp = new BufferedReader(new InputStreamReader(inp));
out = new DataOutputStream(socket.getOutputStream());
} catch (IOException e) {
return;
}
String line;
while (true) {
try {
line = brinp.readLine();
if ((line == null) || line.equalsIgnoreCase("QUIT")) {
socket.close();
return;
} else {
out.writeBytes(line + "\n\r");
out.flush();
}
} catch (IOException e) {
e.printStackTrace();
return;
}
}
}
}
You can also go with more advanced solution, that uses NIO selectors, so you will not have to create thread for every client, but that's a bit more complicated.
This is the echo server handling multiple clients... Runs fine and good using Threads
// echo server
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class Server_X_Client {
public static void main(String args[]){
Socket s=null;
ServerSocket ss2=null;
System.out.println("Server Listening......");
try{
ss2 = new ServerSocket(4445); // can also use static final PORT_NUM , when defined
}
catch(IOException e){
e.printStackTrace();
System.out.println("Server error");
}
while(true){
try{
s= ss2.accept();
System.out.println("connection Established");
ServerThread st=new ServerThread(s);
st.start();
}
catch(Exception e){
e.printStackTrace();
System.out.println("Connection Error");
}
}
}
}
class ServerThread extends Thread{
String line=null;
BufferedReader is = null;
PrintWriter os=null;
Socket s=null;
public ServerThread(Socket s){
this.s=s;
}
public void run() {
try{
is= new BufferedReader(new InputStreamReader(s.getInputStream()));
os=new PrintWriter(s.getOutputStream());
}catch(IOException e){
System.out.println("IO error in server thread");
}
try {
line=is.readLine();
while(line.compareTo("QUIT")!=0){
os.println(line);
os.flush();
System.out.println("Response to Client : "+line);
line=is.readLine();
}
} catch (IOException e) {
line=this.getName(); //reused String line for getting thread name
System.out.println("IO Error/ Client "+line+" terminated abruptly");
}
catch(NullPointerException e){
line=this.getName(); //reused String line for getting thread name
System.out.println("Client "+line+" Closed");
}
finally{
try{
System.out.println("Connection Closing..");
if (is!=null){
is.close();
System.out.println(" Socket Input Stream Closed");
}
if(os!=null){
os.close();
System.out.println("Socket Out Closed");
}
if (s!=null){
s.close();
System.out.println("Socket Closed");
}
}
catch(IOException ie){
System.out.println("Socket Close Error");
}
}//end finally
}
}
Also here is the code for the client.. Just execute this code for as many times as you want to create multiple client..
// A simple Client Server Protocol .. Client for Echo Server
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
public class NetworkClient {
public static void main(String args[]) throws IOException{
InetAddress address=InetAddress.getLocalHost();
Socket s1=null;
String line=null;
BufferedReader br=null;
BufferedReader is=null;
PrintWriter os=null;
try {
s1=new Socket(address, 4445); // You can use static final constant PORT_NUM
br= new BufferedReader(new InputStreamReader(System.in));
is=new BufferedReader(new InputStreamReader(s1.getInputStream()));
os= new PrintWriter(s1.getOutputStream());
}
catch (IOException e){
e.printStackTrace();
System.err.print("IO Exception");
}
System.out.println("Client Address : "+address);
System.out.println("Enter Data to echo Server ( Enter QUIT to end):");
String response=null;
try{
line=br.readLine();
while(line.compareTo("QUIT")!=0){
os.println(line);
os.flush();
response=is.readLine();
System.out.println("Server Response : "+response);
line=br.readLine();
}
}
catch(IOException e){
e.printStackTrace();
System.out.println("Socket read Error");
}
finally{
is.close();os.close();br.close();s1.close();
System.out.println("Connection Closed");
}
}
}
I guess the problem is that you need to start a separate thread for each connection and call serverSocket.accept() in a loop to accept more than one connection.
It is not a problem to have more than one connection on the same port.
See O'Reilly "Java Cookbook", Ian Darwin - recipe 17.4 Handling Multiple Clients.
Pay attention that accept() is not thread safe, so the call is wrapped within synchronized.
64: synchronized(servSock) {
65: clientSocket = servSock.accept();
66: }
Here is code for Multiple Client to one Server Working Fine ..
Give it a try :)
Server.java:
import java.io.DataInputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
class Multi extends Thread{
private Socket s=null;
DataInputStream infromClient;
Multi() throws IOException{
}
Multi(Socket s) throws IOException{
this.s=s;
infromClient = new DataInputStream(s.getInputStream());
}
public void run(){
String SQL=new String();
try {
SQL = infromClient.readUTF();
} catch (IOException ex) {
Logger.getLogger(Multi.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("Query: " + SQL);
try {
System.out.println("Socket Closing");
s.close();
} catch (IOException ex) {
Logger.getLogger(Multi.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public class Server {
public static void main(String args[]) throws IOException,
InterruptedException{
while(true){
ServerSocket ss=new ServerSocket(11111);
System.out.println("Server is Awaiting");
Socket s=ss.accept();
Multi t=new Multi(s);
t.start();
Thread.sleep(2000);
ss.close();
}
}
}
Client1.java:
import java.io.DataOutputStream;
import java.io.ObjectInputStream;
import java.net.Socket;
public class client1 {
public static void main(String[] arg) {
try {
Socket socketConnection = new Socket("127.0.0.1", 11111);
//QUERY PASSING
DataOutputStream outToServer = new DataOutputStream(socketConnection.getOutputStream());
String SQL="I am client 1";
outToServer.writeUTF(SQL);
} catch (Exception e) {System.out.println(e); }
}
}
Client2.java
import java.io.DataOutputStream;
import java.net.Socket;
public class client2 {
public static void main(String[] arg) {
try {
Socket socketConnection = new Socket("127.0.0.1", 11111);
//QUERY PASSING
DataOutputStream outToServer = new DataOutputStream(socketConnection.getOutputStream());
String SQL="I am Client 2";
outToServer.writeUTF(SQL);
} catch (Exception e) {System.out.println(e); }
}
}

Categories