Socket multiple clients - java

Suppose I have 4 clients having port num 1,2,3,4 respectively and one server.
I want to make a connection between server and client and then send clients name and ipaddress to server and simple read that string on server.
In server side socket programming I have used a for loop to access respective clients on port 1,2,3,4.
Now my question is when the client on portnum 2 is not active, server should wait for 1 second and then move to next port num 3 but it is happening so server is stuck in that loop until it makes a connection to portnum 2.
I have used setSoTimeout function but still problem isn't resolved.
Kindly help me
Server Side code is
package server;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Server implements Runnable {
Socket csocket;
Server(Socket csocket) {
this.csocket = csocket;
}
public static void main(String args[])
throws Exception {
for (int i=1; i<=4; i++) {
ServerSocket ssock = new ServerSocket(i);
System.out.println("Listening");
//while (true) {
Socket sock = ssock.accept();
System.out.println("Connected");
new Thread(new Server(sock)).start();
}
}
public void run() {
try {
DataInputStream dis = new DataInputStream(csocket.getInputStream());
String str=dis.readUTF();
System.out.print(str);
dis.close();
csocket.close();
}
catch (IOException e) {
System.out.println(e);
}
}
}
Client side code is
package client;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.*;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client
{
Socket s;
DataOutputStream dout;
public Client() {
while(true)
try {
s=new Socket("192.168.1.101",1);
dout= new DataOutputStream(s.getOutputStream());
java.net.InetAddress j = java.net.InetAddress.getLocalHost();
dout.writeUTF(j.getHostName()+"\t\t\t"+j.getHostAddress());
//Userinfo();
}
catch(Exception e)
{
System.out.println(e);
}
}
// public void Userinfo() throws UnknownHostException, IOException
// {
//
//
// }
public static void main(String as[])
{
new Client();
}
}

Related

How do i establish communication between socket threads of server in order to communicate between clients?

so i'm trying to create a chess server for a chess application i wrote in java. The two classes i'm including are the main class that starts my TCPServerThreads and this class itselve.
I am able to connect two clients and for example echo their input back to them, but i have no idea, how to exchange information between these two threads. I am trying to forward Server inputs from one client towards the main class, or directly to the other client, so i can update the chess field on the client.
It's pretty much my first time working with servers, so thanks in advance for you patience.
This is my main class:
package Main;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import TCP.TCPServerThread;
public class Main {
public static final String StopCode = "STOP";
public static final int PORT = 8888;
public static int count = 0;
public static void main(String[] args) {
ServerSocket serverSocket = null;
Socket socket = null;
//create Server Socket
try {
serverSocket = new ServerSocket(PORT);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("serverSocket created");
//accept client Sockets
while (count < 2) {
try {
socket = serverSocket.accept();
count ++;
System.out.println("socket Nr " + count + " accepted");
} catch (IOException e) {
System.out.println("I/O error: " + e);
}
// new thread for a client
new TCPServerThread(socket).start();
}
}
}
And this is the TCPServerThread:
package TCP;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.sql.Timestamp;
import Main.Main;
public class TCPServerThread extends Thread{
Timestamp ts;
private int port = 0;
Socket socket;
public TCPServerThread(Socket clientSocket) {
this.socket = clientSocket;
}
public void run() {
InputStream is = null;
BufferedReader br = null;
DataOutputStream os = null;
try {
is = socket.getInputStream();
br = new BufferedReader(new InputStreamReader(is));
os = new DataOutputStream(socket.getOutputStream());
} catch (IOException e) {
return;
}
String line;
while (true) {
try {
line = br.readLine();
if ((line == null) || line.equalsIgnoreCase("QUIT")) {
socket.close();
return;
} else {
if(line.equalsIgnoreCase("sp") && this.activeCount() == 3) {
os.writeBytes("1" + "\n\r");
os.flush();
}
os.writeBytes("Echo reply: " + line + "\n\r");
os.flush();
}
} catch (IOException e) {
e.printStackTrace();
return;
}
}
}
}
Thank you very much! I made the tcp threads implement runnable instead of extend thread. Then i added a ConnectionManager between the main and the TCPThreads which isn't static. This way i can put the manager into the TCPThreads constructor and communicate between its objects.

Java - Multi-Threaded Socket Server, How to check a clients connection to the server?

I am wondering how to check if a client is still connected to a server, like to see if the client has crashed, and if not, to check its ping to the server. Im adding all new clients to an ArrayList and when they crash I want to know how to remove them from the list so that I can keep things clean. Im not sure how to do this with Synchronization or if thats possible. If there is a better way too control my threads any advice is welcomed, thanks.
SERVER CODE:
package Main;
import java.io.IOException;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public class MultiThreadedServer implements Runnable{
private static List<Thread> clients = new ArrayList<Thread>();
Socket cs;
private static ServerSocket ss;
private static int port = 25570;
MultiThreadedServer(Socket cs){
this.cs = cs;
}
public static void main(String args[]) throws Exception{
try{
ss = new ServerSocket(port);
System.out.println("Server Listening");
}catch(IOException e){
System.out.println("Port Taken");
}
while(true){
Socket newClient = ss.accept();
System.out.println(newClient.getInetAddress() + " Has Connected");
Thread client = new Thread(new MultiThreadedServer(newClient));
client.start();
clients.add(client);
System.out.println("Connected Clients: " + clients.size());
}
}
public void run(){
try{
PrintStream ps = new PrintStream(cs.getOutputStream());
ps.println("Welcome Client #" + clients.size());
}catch(IOException e){
System.out.println(e);
}
}
}
CLIENT CODE:
package Main;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client{
private static String ip = "127.0.0.1";
private static int port = 25570;
public static void main(){
Socket socket;
BufferedReader reader;
PrintWriter writer;
try {
socket = new Socket(ip,port);
BufferedReader in = new BufferedReader(new
InputStreamReader(socket.getInputStream()));
OutputStreamWriter os = new
OutputStreamWriter(socket.getOutputStream());
PrintWriter out = new PrintWriter(os);
System.out.println(in.readLine());
} catch (UnknownHostException e) {
System.out.println("ERROR UNKNOWN");
e.printStackTrace();
} catch (IOException e) {
System.out.println("Could not connect to server!");
e.printStackTrace();
return;
}
}
}

How just send messages to other clients?

I have a question with java sockets. My code sends messages to all clients, including sending. I want him to send only for other clients How can I do this? I test using telnet 127.0.0.1 2015 command in the terminal.
Client
package socket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class Clientes implements Runnable {
public Socket cliente;
public Clientes(Socket cliente) {
this.cliente = cliente;
}
public void run() {
try {
PrintWriter out = new PrintWriter(cliente.getOutputStream(), true);
out.write("---Seja Bem Vindo---\n");
out.flush();
System.out.println("Nova conexao: "
+ this.cliente.getInetAddress().getHostAddress());
while (true) {
BufferedReader in = new BufferedReader(new InputStreamReader(
cliente.getInputStream()));
String veioDoCliente = in.readLine();
if(veioDoCliente.equalsIgnoreCase("SAIR")){
cliente.close();
break;
}
System.out.println("MSG vinda do cliente " + veioDoCliente);
for (Clientes writer : Servidor.clientes) {
PrintWriter out2 = new PrintWriter(writer.cliente.getOutputStream(), true);
out2.write("teste:"+veioDoCliente+"\n");
out2.flush();
}
//s.close();
//this.cliente.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Server
package socket;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public class Servidor {
public Socket cliente;
public Servidor(Socket cliente) {
this.cliente = cliente;
}
public static List<Clientes> clientes = new ArrayList<Clientes>();
public static void main(String[] args) throws IOException {
ServerSocket servidor = new ServerSocket(2015);
System.out.println("Esperando alguem se conectar...");
while (true) {
Socket cliente = servidor.accept();
Clientes tratamento = new Clientes(cliente);
clientes.add(tratamento);
Thread t = new Thread(tratamento);
t.start();
}
}
}
I'm not seeing where your server is handling the code coming in, so I'm shooting in the dark.
Basically, when your data comes in, you see which client it originated from and then check in your loop to see if that client matches the current client. If no match, then send the data out.
If not possible any other way, you will need to give each client and ID and it will send the data with the ID string, but I'm sure that you can keep track of your clients using the socket.

Unexpected 40ms ping

I'm experiencing a weird issue, and I can't figure out what is occurring.
So basically, when I try to make a simple connection between a server and a client with an exchange of a float number (with DataInputStream and DataOutputStream), it seems that there is a fixed ping limit, exactly 40ms on three different computers with openjdk.
Furthermore, I tried to change the way I send the float number with:
outs.write(ByteBuffer.allocate(4).putFloat(3.14f).array(), 0, 4);
which is supposed to do the same thing as:
outs.writeFloat(3.14f);
and this odd ping limit surprisingly vanished!
Maybe I am doing something wrong with the following code:
client side
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketException;
import java.io.IOException;
import java.io.DataOutputStream;
import java.io.DataInputStream;
import java.nio.ByteBuffer;
public class client {
private Socket sock;
private DataOutputStream outs;
private DataInputStream ins;
public client() throws IOException{
byte c;
sock = new Socket(InetAddress.getByName("localhost"),9998);
outs = new DataOutputStream(sock.getOutputStream());
ins = new DataInputStream(sock.getInputStream());
do{
long start = System.currentTimeMillis();
/* here is the thing */
//outs.write(ByteBuffer.allocate(4).putFloat(3.14f).array(), 0, 4); // either this outs
outs.writeFloat(3.14f); // or this one
outs.flush();
c = ins.readByte();
long stop = System.currentTimeMillis();
System.out.println("elapsed time: "+(stop-start)+"ms");
}while(c == (byte) 1);
}
public static void main(String[] args) {
try{
client client = new client();
} catch(SocketException e){
System.out.println("Socket disconnected");
} catch (IOException e) {
e.printStackTrace();
}
}
}
server
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.ServerSocket;
import java.io.IOException;
import java.io.DataOutputStream;
import java.io.DataInputStream;
public class server extends Thread{
private DataOutputStream outs;
private DataInputStream ins;
public server(Socket sock) throws IOException{
System.out.println("client connected");
outs = new DataOutputStream(sock.getOutputStream());
ins = new DataInputStream(sock.getInputStream());
}
public void run(){
try{
while(true){
float f = ins.readFloat();
System.out.println("value: "+f);
outs.writeByte((byte) 1);
outs.flush();
}
} catch (IOException e) {
System.out.println("client disconnected");
}
}
public static void main(String[] args) {
try{
ServerSocket serverSock = new ServerSocket(9998);
while(true){
server server = new server(serverSock.accept());
server.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
which gives me (on localhost) with the usual writeFloat:
elapsed time: 40ms
else with write():
elapsed time: 0ms
Edit :
Apparently, it seems that Mike's answer solved the issue! No more 40ms latency with writeFloat...
Windows? Try to increase the number of bytes you send. There is (or was) a limit within the Windows TCP/IP stack, which waits for an amount of time the get get more bytes to get a full Package to send.

Why can't send the correct data with sockets? JAVA (Client-Server Program running on local)

i'm trying to make a server client program in java. I'm trying to run on same system. It sends a text file from client to server including names etc. But when the server gets the file it just prints "[]" characters. Does that mean null or does that mean corrupted data?
Here is the server;
package temel;
import java.io.File;
import java.io.InputStream;
import java.net.Socket;
import java.net.ServerSocket;
public class VeriAlma {
private static int port;
private static Socket socket;
public VeriAlma(int port)
{
VeriAlma.port=port;
}
public static void veriAl() {
try {
ServerSocket listener = new ServerSocket(port);
socket = listener.accept();
}
catch (java.lang.Exception ex) {
ex.printStackTrace(System.out);
}
}
public String run() {
try {
InputStream in = socket.getInputStream();
String file_name = "x.txt";
File file=new File(file_name);
ByteStream.toFile(in, file);
return file_name;
}
catch (java.lang.Exception ex) {
ex.printStackTrace(System.out);
return "asdasd";
}
}
public void setPort(int port)
{
VeriAlma.port=port;
}
}
Here is the client
package temel;
import java.io.*;
import java.net.*;
import java.lang.*;
import java.io.OutputStream;
import java.io.InputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.net.Socket;
public class VeriGonderme {
// host and port of receiver
private static int port;
private static String host;
public VeriGonderme(int port,String host)
{
this.port=port;
this.host=host;
}
public void veriGonder(String dosyaIsmi) {
try {
Socket socket = new Socket(host, port);
OutputStream os = socket.getOutputStream();
ByteStream.toStream(os, 1);
ByteStream.toStream(os, dosyaIsmi);
ByteStream.toStream(os, new File(dosyaIsmi));
}catch (Exception ex) {
ex.printStackTrace();
}
}
public void setPort(int port)
{
this.port=port;
}
public void setHost(String host)
{
this.host=host;
}
}
host is "localhost" port is 4444
This is the original code i modified it a little bit
But when the server gets the file it just prints "[]" characters.
I would expect to see some characters like this because you are sending the value 1 as a 4 byte binary. i.e. \0\0\0\u0001 If you remove this and only send the file once, it may do as you expected.

Categories