Let me explain my work.
I have to send a file from server to client. In server I accepted the connection from the client and not closed the connection. Now I have to send the data as streams to the client.
Now I have selected a content and wrote in a file in method.
I have send method in which I have to send the file in inputstreams to the client. How to send?
public static void main(String args[])
{
int port=5000;
while(true)
{
try
{
ServerSocket ser=new ServerSocket(port+10);
System.out.println("CLIENT A IS CONNECTED");
ser.close();
}
catch(Exception e)
{
System.out.println(e);
}
try
{
ServerSocket ser1=new ServerSocket(port+20);
ser1.accept();
System.out.println("CLIENT B IS CONNECTED");
}
catch(Exception e)
{
System.out.println(e);
}
try
{
ServerSocket ser2=new ServerSocket(port+30);
ser2.accept();
System.out.println("CLIENT C IS CONNECTED");
}
catch(Exception e)
{
System.out.println(e);
}
try
{
ServerSocket ser3=new ServerSocket(port+40);
ser3.accept();
System.out.println("CLIENT D IS CONNECTED");
}
catch(Exception e)
{
System.out.println(e);
}
}
}
In main method I accepted All the client request.
private void jButton1ActionPerformed1(java.awt.event.ActionEvent evt) //sendbutton
{
try
{
FileReader buf=new FileReader("e:\\input.txt");
int port= // the port of client which I selected to send the data
try
{
#SuppressWarnings("resource")
ServerSocket ser=new ServerSocket(port);
Socket soc=ser.accept();
BufferedReader toclient=new BufferedReader(buf);
DataOutputStream dos=new DataOutputStream(soc.getOutputStream());
System.out.println(dos.toString());
dos.flush();
dos.close();
}
catch(Exception e)
{
System.out.println(e);
}
}
catch(Exception e)
{
System.out.println(e);
}
}
Now my question is I already opened the ports and the connection is established in the main method. I have to send the data from server to client by selecting to which client should receive the data in sendbutton method. I am confused how to check or pass the socket object serv1 to the send method?.
below is the sample server code (please add corresponding import statements and your logic)
class SampleServer
{
private int port;
private ArrayList clientList;
public SampleServer()
{
this.port = 4444;
}
public SampleServer(int port)
{
this.port = port;
}
public void startServer()
{
ServerSocket ss = new ServerSocket(this.port);
Socket soc;
while(true)
{
soc = ss.accept();
clientList.add(soc);
}
}
public ArrayList getClientList()
{
return clientList;
}
}
Below is the sample main method (take this as a reference and create your own code)
public class Main
{
public static void main(String[] args) throws Exception
{
//Create a server
//Server has to be only one and multiple clients can connect it
SampleServer server = new SampleServer(5555);
server.startServer();
//Creating one client
Socket soc = new Socket("localhost", 5555);
//Similarly create n-number of clients and connect to the same port as that of server
//server.getClientList(); will help you get the list of the clients connected to the server
}
}
Related
A client communicate with authserver to recieve a nickname, and the auhserver send the nickname to clients and another server, in order to client communicate with the other server.
My problem is how to make the other server connect with the client and authserver without making new communication thread for each one?
public class Aatombolaserver extends Thread {
/***in order to differentiate between client socket**/
protected Socket clientSocket;
String serverHostname = new String ("127.0.0.1");
Socket authSocket = null;
/**** constructor**/
private Aatombolaserver (Socket clientSoc)
{clientSocket = clientSoc;
authSocket = clientSoc;
//store the socket of the coming client
start();//execute the run method
}
public static void main(String[] args) throws IOException
{
/**** Create a server socket and wait for a connection**/
ServerSocket serverSocket = null;
// ServerSocket serverSocket1 = null;
try {
serverSocket = new ServerSocket(9091);
// serverSocket1 = new ServerSocket(9092);
System.out.println ("Connection Socket Created");
try { System.out.println ("Waiting for a client to connect");
while (true){//wait for clients
//accept the client request and proceed with the thread creation
new Aatombolaserver(serverSocket.accept());
}
}
catch (IOException e){
System.err.println("Accept failed.");
System.exit(1);
}
} catch (IOException e) {
System.err.println("Could not listen on port: 10008.");
System.exit(1);
}//end try
/************Close Socket*******************/
finally {
try { serverSocket.close(); }
catch (IOException e){
System.err.println("Could not close port: 10008.");
System.exit(1);
}
}//end finally
}
I am writing a program to eventually make my own file server. I am having issues with connecting to the server in a web browser via typing myIpAddress:port into the browser while the server is running. This does work if I use one computer to both host the server and be a client, but does not if I use a second computer to be a client.
I have 2 classes, Index and ClientHandler
public class Index {
public static void main(String[] args) {
ServerSocket server = null;
try {
server = new ServerSocket(8080);
DevInterface myFace = new DevInterface(server);
System.out.println("Listening for connection on port 8080");
} catch (IOException e) {
e.printStackTrace();
}
int i = 0;
while(true) {
Socket client = null;
try {
client = server.accept();
ClientHandler clientHandler = new ClientHandler(client);
clientHandler.start();
System.out.println("got a client");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
and my ClientHandler class which is what sends my html to the server is this.
public class ClientHandler extends Thread{
private Socket client = null;
private PrintWriter out = null;
ArrayList<Socket> clientList = null;
public ClientHandler(Socket client) {
this.client = client;
}
public ClientHandler(Socket client, ArrayList<Socket> clientList) {
this.client = client;
this.clientList = clientList;
}
public void run() {
try {
out = new PrintWriter(client.getOutputStream());
out.println("HTTP/1.1 200 OK");
out.println("Content-Type: text/html");
out.println("\r\n");
out.println("<p>Hello World</p>");
out.flush();
out.close();
if(client!=null) {client.close();}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I think it's because when I multi-thread the client&server, the DataOutputStream and DataInputStream buffers I use get overwritten or something like that since the socket can only have 1 duplex connection.
Here's what I have for now:
Client Class in my client program:
public static void main(String args[]) throws UnknownHostException, IOException, InterruptedException {
for (int i=0;i<2;i++) //change limit on i to change number of threads
{
new Thread(new ClientHandler(i)).start();
}
Thread.sleep(10000);
ClientHandler class in my client program:
(Sends a value to the server, the server will echo it back).
public class ClientHandler implements Runnable {
public int clientNumber;
public ClientHandler(int i){
this.clientNumber=i;
}
public void run() {
Socket socket = null;
try {
socket = new Socket("localhost",9990);
System.out.println("connected client number "+clientNumber);
DataOutputStream output = new DataOutputStream(socket.getOutputStream());
DataInputStream input = new DataInputStream(socket.getInputStream());
output.writeDouble((new Random()).nextDouble());
System.out.println(input.readDouble());
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
Server Class in my server program:
ServerSocket socket = new ServerSocket(9990);
try {
while (true) {
Socket threadSocket = socket.accept();
new Thread(new ServerHandler(threadSocket)).start();
Thread.sleep(10000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
finally {
socket.close();
}
}
}
ServerHandler Class in my server program (receives value from client and echoes it back)
public class ServerHandler implements Runnable {
private Socket socket;
public ServerHandler(Socket socket) {
this.socket = socket;
}
public void run() {
while(true) {
try {
DataInputStream input = new DataInputStream(socket.getInputStream());
DataOutputStream output = new DataOutputStream(socket.getOutputStream());
double a = input.readDouble();
output.writeDouble(a);
}catch (IOException e){
e.printStackTrace();
}
}
}
So it's a pretty straight-forward implementation: create multiple threads of the client, and connect them to multiple threads of the server.
Everything works fine until the line:
double a = input.readDouble();
in my ServerHandler class.
I get an EOFException
I'm guessing it's because there can only be a single duplex connection between sockets. But if that's the case then how would I implement multi-threading of sockets at all?
So my question is: how can I get rid of the EOFException and allow myself to perform multi-threaded client-server socket interaction?
(preferably not changing much about my code because it's taken me a long time to get to this point).
The problem is that you share same Socket variable in ServerHandler for all threads:
private static Socket socket
Remove static keyword. Your ServerHandler will be something like this:
public static class ServerHandler implements Runnable {
private Socket socket;
public ServerHandler(Socket socket) {
this.socket = socket;
}
public void run() {
try {
DataInputStream input = new DataInputStream(socket.getInputStream());
DataOutputStream output = new DataOutputStream(socket.getOutputStream());
double a = input.readDouble();
output.writeDouble(a);
} catch (IOException e) {
e.printStackTrace();
}
}
}
i want to make a game with 2 players .i will use udp server and 2 clients and i dont
know how to connect 2 clients to 1 server at the same time and how they will communicate.
I will use only java.At last how the mouse click will syncronize with server
public void mousePressed(MouseEvent event) {
}
public void mouseReleased(MouseEvent event) {
}
public void mouseEntered(MouseEvent event) {
}
public void mouseExited(MouseEvent event) {
}
the server
public class Provider {
public ServerSocket providerSocket;
Socket connection = null;
ObjectOutputStream out;
ObjectInputStream in;
String message;
String[] torino={"null","null"};
Provider() {}
void run()
{
try {
//1. creating a server socket (8080=port , 2 =number of connections)
providerSocket = new ServerSocket(8080, 2 );
//2. Wait for connection
System.out.println("Waiting for connection");
connection = providerSocket.accept();
System.out.println("Connection received from " + connection.getInetAddress().getHostName());
//3. get Input and Output streams
out = new ObjectOutputStream(connection.getOutputStream());
// flush= clean the object out
out.flush();
in = new ObjectInputStream(connection.getInputStream());
sendMessage("Connection successful");
//4. The two parts communicate via the input and output streams
try {
//take the message from client
message = (String)in.readObject();
if (torino[0]=="null")
torino[0]=message;
} else if (torino[1]=="null") {
torino[1]=message;
}
}
catch(ClassNotFoundException classnot) {
System.err.println("Data received in unknown format");
}
} catch(IOException ioException) {
ioException.printStackTrace();
}
finally {
//4: Closing connection
try {
in.close();
out.close();
providerSocket.close();
} catch(IOException ioException) {
ioException.printStackTrace();
}
}
}
//method to send messages from server to clients
void sendMessage(String msg)
{
try {
out.writeObject(msg);
out.flush();
System.out.println("server>" + msg);
}
catch(IOException ioException) {
ioException.printStackTrace();
}
}
//main method
public static void main(String args[])
{
Provider server = new Provider();
while(true) {
server.run();
}
}
So now you can see in your code that you have a point where the server socket is waiting for a connection. That is the accept() method. At that point, you need to create a new Thread for handling the connection and let the main thread continue waiting for another connection. You may want to keep track of the number of connections made in a variable, say numConnections.
while(numConnections < 2){
connection = providerSocket.accept();
Thread t = new Thread(new ConnectionHandler(connection));
t.start();
numConnections++;
}
Now you ConnectionHandler class will do the work of the connection:
class ConnectionHandler implements Runnable{
Socket connection;
public ConnectionHandler(Socket connection){
this.connection = connection;
}
public void run(){
//here you do all the code associated with handling the connection
//such as your Object Streams and so on.
}
}
A quick Google search turns up many tutorials and examples of doing this such as this one. There are also some YouTude videos. You may want to start with one of those.
So now, I am making a client server app based multithread. In server side, I make a thread for everysingle connection that accepted.
In thread class, I make a method that send a command to client. What i just want is, how to send a parameter to all running client? For simple statement, i just want to make this server send a message to all connected client.
I've been read this post and find sendToAll(String message) method from this link. But when i am try in my code, there is no method like that in ServerSocket .
Okay this is my sample code for server and the thread.
class ServerOne{
ServerSocket server = null;
...
ServerOne(int port){
System.out.println("Starting server on port "+port);
try{
server = new ServerSocket(port);
System.out.println("Server started successfully and now waiting for client");
} catch (IOException e) {
System.out.println("Could not listen on port "+port);
System.exit(-1);
}
}
public void listenSocket(){
while(true){
ClientWorker w;
try{
w = new ClientWorker(server.accept());
Thread t = new Thread(w);
t.start();
} catch (IOException e) {
System.out.println("Accept failed: 4444");
System.exit(-1);
}
}
}
protected void finalize(){
try{
server.close();
} catch (IOException e) {
System.out.println("Could not close socket");
System.exit(-1);
}
}
}
class ClientWorker implements Runnable{
Socket client;
ClientWorker(Socket client){
this.client = client;
}
public void run(){
...
sendCommand(parameter);
...
}
public void sendCommand(String command){
PrintWriter out = null;
try {
out = new PrintWriter(client.getOutputStream(), true);
out.println(command);
} catch (IOException ex) {}
}
}
Thanks for help :)
The below answer, is not recommended for a full fledged server, as for this you should use Java EE with servlets, web services etc.
This is only intended where a few computers want to connect to perform a specific task, and using simple Java sockets is not a general problem. Think of distributed computing or multi-player gaming.
EDIT: I've - since first post - greatly updated this architecture, now tested and thread-safe. Anybody who needs it may download it here.
Simply use (directly, or by subclassing) Server and Client, start() them, and everything is ready. Read the inline comments for more powerful options.
While communication between clients are fairly complicated, I'll try to simplify it, the most possible.
Here are the points, in the server:
Keeping a list of connected clients.
Defining a thread, for server input.
Defining a queue of the received messages.
A thread polling from the queue, and work with it.
Some utility methods for sending messages.
And for the client:
Defining a thread, for client input.
Defining a queue of the received messages.
A thread polling from the queue, and work with it.
Here's the Server class:
public class Server {
private ArrayList<ConnectionToClient> clientList;
private LinkedBlockingQueue<Object> messages;
private ServerSocket serverSocket;
public Server(int port) {
clientList = new ArrayList<ConnectionToClient>();
messages = new LinkedBlockingQueue<Object>();
serverSocket = new ServerSocket(port);
Thread accept = new Thread() {
public void run(){
while(true){
try{
Socket s = serverSocket.accept();
clientList.add(new ConnectionToClient(s));
}
catch(IOException e){ e.printStackTrace(); }
}
}
};
accept.setDaemon(true);
accept.start();
Thread messageHandling = new Thread() {
public void run(){
while(true){
try{
Object message = messages.take();
// Do some handling here...
System.out.println("Message Received: " + message);
}
catch(InterruptedException e){ }
}
}
};
messageHandling.setDaemon(true);
messageHandling.start();
}
private class ConnectionToClient {
ObjectInputStream in;
ObjectOutputStream out;
Socket socket;
ConnectionToClient(Socket socket) throws IOException {
this.socket = socket;
in = new ObjectInputStream(socket.getInputStream());
out = new ObjectOutputStream(socket.getOutputStream());
Thread read = new Thread(){
public void run(){
while(true){
try{
Object obj = in.readObject();
messages.put(obj);
}
catch(IOException e){ e.printStackTrace(); }
}
}
};
read.setDaemon(true); // terminate when main ends
read.start();
}
public void write(Object obj) {
try{
out.writeObject(obj);
}
catch(IOException e){ e.printStackTrace(); }
}
}
public void sendToOne(int index, Object message)throws IndexOutOfBoundsException {
clientList.get(index).write(message);
}
public void sendToAll(Object message){
for(ConnectionToClient client : clientList)
client.write(message);
}
}
And here for the Client class:
public class Client {
private ConnectionToServer server;
private LinkedBlockingQueue<Object> messages;
private Socket socket;
public Client(String IPAddress, int port) throws IOException{
socket = new Socket(IPAddress, port);
messages = new LinkedBlokingQueue<Object>();
server = new ConnecionToServer(socket);
Thread messageHandling = new Thread() {
public void run(){
while(true){
try{
Object message = messages.take();
// Do some handling here...
System.out.println("Message Received: " + message);
}
catch(InterruptedException e){ }
}
}
};
messageHandling.setDaemon(true);
messageHandling.start();
}
private class ConnectionToServer {
ObjectInputStream in;
ObjectOutputStream out;
Socket socket;
ConnectionToServer(Socket socket) throws IOException {
this.socket = socket;
in = new ObjectInputStream(socket.getInputStream());
out = new ObjectOutputStream(socket.getOutputStream());
Thread read = new Thread(){
public void run(){
while(true){
try{
Object obj = in.readObject();
messages.put(obj);
}
catch(IOException e){ e.printStackTrace(); }
}
}
};
read.setDaemon(true);
read.start();
}
private void write(Object obj) {
try{
out.writeObject(obj);
}
catch(IOException e){ e.printStackTrace(); }
}
}
public void send(Object obj) {
server.write(obj);
}
}
There is no method in server socket to send data or message to all running clinet threads.
Please go through the ServerThread.java program which is calling the sendToAll usng server.
// ... and have the server send it to all clients
server.sendToAll( message );
Check out zeroMQ. There are methods known as "pub sub" or "publish subscribe" that will do what you want. You can also use it to communicate between your threads. It is an amazing library in my opinion. It has java or jzmq bindings along with over 30+ others as well so you should be able to use it in your program.
http://www.zeromq.org/