I am using a data generator which uses ports for streaming data. I use multiple ports mfor receiving data. The software I am writing makes a new socket for each port. Every socket should make an instance of a class called 'Interpreter'.
The problem I have is the following: I am able to make multiple instances of Interpreter, but I think the data is all being parsed to only one of the instances. I think this happens because the data is 'merged' in the output.
This is the most important snipet of the code:
public class Main {
public static void main (String[] args) {
Socket socket;
ServerSocket serverSocket=null;
System.out.println("Server Listening..");
try{
serverSocket = new ServerSocket(7789);
}
catch(IOException e){
e.printStackTrace();
System.out.println("Error");
}
while(true){
try{
socket= serverSocket.accept();
Interpreter interp = new Interpreter();
ServerThread serverThr=new ServerThread(socket, interp);
serverThr.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, Interpreter interp) {
this.interp = interp;
this.s = s;
System.out.println("interp "+interp);
System.out.println("s: "+s);
System.out.println("poort: "+s.getPort());
}
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();
Interpreter.interpreter(line);
line = is.readLine();
}
} catch (IOException e) {
line = this.getName();
System.out.println("IO Error/ Client " + line + " terminated abruptly");
} catch (NullPointerException e) {
line = this.getName();
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");
}
}
}
}
This is the 'important' part of Interpreter:
public class Interpreter{
static AtomicInteger nextId = new AtomicInteger();
int id = nextId.incrementAndGet();
public Interpreter(){
System.out.println("ID of demo "+id);
}
}
Related
I have created a quizServer application in java swing that connects to multiple clients through a socket. I am able to send data to the server from each client simultaneously through the socket connection but when I try to send data to the clients from the server then it is being received by only 1 client. How can I modify the code to send data to all the clients listening on the socket at the same time? Any code/pseudo-code will be appreciated.
This is my NetworkClient class:
public class NetworkClient {
PrintWriter os = null;
Socket s1 = null;
String line = null;
BufferedReader br = null;
BufferedReader is = null;
InetAddress address = null;
void initClient() {
try {
address = InetAddress.getLocalHost();
System.out.println(address);
} catch (UnknownHostException ex) {
Logger.getLogger(NetworkClient.class.getName()).log(Level.SEVERE, null, ex);
}
try {
s1 = new Socket(address, 8888); // 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");
}
}
void sendVal(int data) {
os.println(data);
os.flush();
}
void close() {
try {
is.close();
os.close();
br.close();
s1.close();
} catch (Exception ex) {
Logger.getLogger(NetworkClient.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Here is my Server class:
public class QuizServer {
QuizJFrame frame;
ServerThread st;
void initServer(QuizJFrame frm) {
frame = frm;
Socket s = null;
ServerSocket ss2 = null;
System.out.println("Server Listening......");
try {
ss2 = new ServerSocket(8888); // port number used as 8888
} catch (IOException e) {
e.printStackTrace();
System.out.println("Server error");
}
while (true) {
try {
s = ss2.accept();
System.out.println("connection Established");
st = new ServerThread(s, frm);
st.start();
} catch (Exception e) {
e.printStackTrace();
System.out.println("Connection Error");
}
}
}
}
This is the server thread class:
class ServerThread extends Thread {
BufferedReader is = null;
PrintWriter os = null;
Socket s = null;
QuizJFrame frame;
String question[] = {"", "QUESTION 1", "QUESTION 2", "QUESTION 3", "QUESTION 4", "END"};
int answer[] = {0, 1, 2, 3, 4};
int index;
public ServerThread(Socket s, QuizJFrame frm) {
this.s = s;
frame = frm;
index = 1;
frame.setQuestion(question[index]);
}
#Override
public void run() {
int option = 0;
try {
is = new BufferedReader(new InputStreamReader(s.getInputStream()));
os = new PrintWriter(s.getOutputStream());
} catch (IOException e) {
System.out.println("IO error in server thread:" + e);
}
try {
while (option > -1) {
try {
option = Integer.parseInt(is.readLine());
os.println(answer[index] == option);
os.flush();
} catch (NumberFormatException e) { //to handle null value
}
System.out.println(result(option));
frame.output(result(option));
}
} catch (IOException ex) {
Logger.getLogger(ServerThread.class.getName()).log(Level.SEVERE, null, ex);
}
}
String result(int op) {
if (op == -1) {
return "Client exited";
}
if (answer[index] == op) {
return "Option " + op + " is the correct answer.";
} else {
return "Option " + op + " is incorrect.";
}
}
void nextQues() {
index++;
frame.setQuestion(question[index]);
os.println(-2);
os.flush();
}
}
EDIT : Using List<ServerThread> resolved the issue.
Your server has only one ServerThread variable, and thus can only send data to one socket, the last one added. Instead, consider giving the class an List<ServerThread> variable to allow it to communicate with all the clients. Then in the while loop where you create connections, add each newly created ServerThread to this list.
You'll also need to fix your server's threading issues so that the while (true) loop doesn't block key code.
You'll also need to upgrade the ServerThread class so that the main server object can communicate with its streams.
Also you almost never want to have a class extend Thread. Have it implement Runnable instead.
I'm trying to create a proxy application, but I'm facing problems in server socket. The Server Socket is not accepting the connection and returning a socket. Hence, I cannot test the proxy application. What is wrong?
The problem line is indicated in WebServe.java:
public class WebServe implements Runnable {
Socket soc;
OutputStream os;
BufferedReader is;
String resource;
WebServe(Socket s) throws IOException {
soc = s;
os = soc.getOutputStream();
is = new BufferedReader(new InputStreamReader(soc.getInputStream()));
}
public void run() {
System.err.println("Running");
getRequest();
returnResponse();
close();
}
public static void main(String args[]) {
try {
System.out.println("Proxy Thread");
ServerSocket s = new ServerSocket(8080);
for (;;) {
s.setSoTimeout(10000);
WebServe w = new WebServe(s.accept()); // Problem is here
Thread thr = new Thread(w);
thr.start();
w.getRequest();
w.returnResponse();
w.close();
}
} catch (IOException i) {
System.err.println("IOException in Server");
}
}
void getRequest() {
System.out.println("Getting Request");
try {
String message;
while ((message = is.readLine()) != null) {
if (message.equals("")) {
break;
}
System.err.println(message);
StringTokenizer t = new StringTokenizer(message);
String token = t.nextToken();
if (token.equals("GET")) {
resource = t.nextToken();
}
}
} catch (IOException e) {
System.err.println("Error receiving Web request");
}
}
void returnResponse() {
int c;
try {
FileInputStream f = new FileInputStream("." + resource);
while ((c = f.read()) != -1) {
os.write(c);
}
f.close();
} catch (IOException e) {
System.err.println("IOException is reading in web");
}
}
public void close() {
try {
is.close();
os.close();
soc.close();
} catch (IOException e) {
System.err.println("IOException in closing connection");
}
}
}
public static void main(String args[]){
try {
System.out.println("Proxy Thread");
ServerSocket s = new ServerSocket (8080);
for (;;){
s.setSoTimeout(10000);
Move that ahead of the loop. You don't need to keep setting it. You don't really need it at all actually.
WebServe w = new WebServe (s.accept()); //Problem is here
The problem is here only because you set a socket timeout you don't actually need.
Thread thr = new Thread (w);
thr.start();
So far so good.
w.getRequest();
w.returnResponse();
w.close();
Remove. The next problem is here. The run() method of WebServ already does this.
As to the rest, you aren't writing an HTTP header in the response.
I made a little game. Now i want to get the highscore from my Server. The code on the client:
private int getOnlineHighscore() {
int highscore = 0;
try {
socket = new Socket("localhost", 444);
input = socket.getInputStream();
System.out.println(input);
highscore = input.read();
input.close();
socket.close();
input = null;
socket = null;
} catch (Exception e) {
System.out.println("Verbindung fehlgeschlagen!");
}
System.out.println(highscore);
return highscore;
}
And on the Server:
import java.io.*;
import java.net.*;
public class ReadServer extends Thread {
private Socket socket;
public ReadServer(Socket socket) {
super();
this.socket = socket;
}
public void run() {
try {
System.out.println(socket.getInetAddress());
String result = "";
try (BufferedReader br = new BufferedReader(
new FileReader(System.getProperty("user.home") + "/AppData/Roaming/GameServer/.sg"))) {
StringBuilder sb = new StringBuilder();
String line = br.readLine();
System.out.println("2");
while (line != null) {
sb.append(line);
sb.append(System.lineSeparator());
line = br.readLine();
}
System.out.println("3");
result = sb.toString();
System.out.println("3.5");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("4");
socket.getOutputStream().write(Integer.parseInt(result));
System.out.println(result);
} catch (Exception e) {
}
try {
socket.close();
} catch (Exception e) {
}
}
public static void main(String[] Args) {
Socket socket = null;
ServerSocket server = null;
try {
server = new ServerSocket(444);
while (true) {
socket = server.accept();
new ReadServer(socket).start();
}
} catch (Exception e) {
}
try {
server.close();
} catch (Exception e) {
}
}
}
If I run it, the client function returns:
-1
The server writes in the console(not important I think):
/127.0.0.1
2
3
3.5
4
How to solve the problem? I want to send an int stored on my Server to a client.
-Jakob
-1 is returned by read() to specify end of stream , make sure data to be read is being returned .
What is the highscore stored in the file? I believe the file is empty and it fails on parsing the integer but as your catch block is empty, you don't see the exception. Put printStacktrace or rethrow.
Another problem is that OutputStream sends only bytes and therefore write method sends only low 8 bits. To send int wrap the stream with DataOutputStream and DataInputStream on the client side.
I have a server to get a response headers through which I detect the type of device. Is there any way I can get the Internet speed through response headers or any other method ?
Server_X:
public class Server_X {
static int count = 0;
public static void main(String args[]) {
Socket s = null;
ServerSocket ss2 = null;
System.out.println("Server Listening......");
try {
// can also use static final PORT_NUM, when defined
ss2 = new ServerSocket(4445);
} 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);
count++;
System.out.println("total connections :" + count);
st.start();
}
catch (Exception e) {
e.printStackTrace();
System.out.println("Connection Error");
}
}
}
}
ServerThread:
class ServerThread extends Thread {
static String uagent, uaccept;
static String[] b;
static String[] c;
Server_X obj = new Server_X();
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(line);
line = is.readLine();
b = line.split(":");
if (b[0].equals("User-Agent")) {
uagent = b[1];
// System.out.println(uagent);
}
c = line.split(":");
if (c[0].equals("Accept")) {
uaccept = c[1];
// System.out.println(uaccept);
}
UAgentInfo detect = new UAgentInfo(uagent, uaccept);
}
} 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");
obj.count--;
System.out.println("Toatal connections (after closing):"
+ obj.count);
}
} catch (IOException ie) {
// System.out.println("Socket Close Error");
}
}// end finally
}
}
You didn't specify what protocol the server is using; I suppose is HTTP since you're catching "User-Agent" and "Accept". If I'm correct, there's no header with the information you're looking for, as you can check on https://en.wikipedia.org/wiki/List_of_HTTP_header_fields.
In this code I can correctly receive a request using BufferedReader inClient, created on the client socket.
Then I send the request to the server and I see the server gets it.
But then, when I try to read the reply from the server (using BufferedReader inServer on the socket of the server), it always ends in IOException: Impossible read from server.
I am referring to the block ################
Do you know any possible reasons?
import java.io.*;
import java.net.Socket;
import java.net.ServerSocket;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class ProxyMain {
public static void main(String argv[]) {
int proxyPort = 55554;
String proxyAddr = "127.0.0.1";
ServerSocket proxySocket = null;
try {
proxySocket = new ServerSocket(proxyPort, 50, InetAddress.getByName("127.0.0.1"));
}
catch (Exception e) {
System.err.println("Impossible to create socket server!");
System.out.flush();
System.exit(1);
}
System.out.printf("Proxy active on port: %d and on address %s\n", proxyPort, proxySocket.getInetAddress());
System.out.println();
while (true) {
Socket client = null;
Socket sockServ = null;
BufferedReader inClient = null;
PrintWriter outClient = null;
BufferedReader inServer = null;
PrintWriter outServer = null;
String request = new String();
String tmp = new String();
String reply = new String();
String tmpReply = new String();
try {
client = proxySocket.accept();
System.out.println("Connected to: ");
System.out.println(client.getInetAddress().toString());
System.out.printf("On port %d\n", client.getPort());
System.out.println();
inClient = new BufferedReader(new InputStreamReader(client.getInputStream()));
outClient = new PrintWriter(client.getOutputStream(), true);
}
/*catch (IOException e) {
System.err.println("Couldn't get I/O for connection accepted");
System.exit(1);
}*/
catch (Exception e) {
System.out.println("Error occurred!");
System.exit(1);
}
System.out.println("Received request:");
try{
for (int i = 0; i<2; i++) {
tmp = inClient.readLine();
request = request + tmp;
}
inClient.close();
}
catch (IOException ioe) {
System.err.println("Impossible to read mhttp request!");
System.exit(1);
}
System.out.println(request);
System.out.println();
try {
sockServ = new Socket("127.0.0.1", 55555);
outServer = new PrintWriter(sockServ.getOutputStream(), true);
inServer = new BufferedReader(new InputStreamReader(sockServ.getInputStream()));
}
catch (UnknownHostException e) {
System.err.println("Don't know about host: 127.0.0.1:55555");
System.exit(1);
}
catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to: 127.0.0.1:55555");
System.exit(1);
}
outServer.println(request);
outServer.close();
try {
#################################################
while ((tmpReply = inServer.readLine()) != null) {
System.out.println(tmpReply);
reply = reply + tmpReply;
}
inServer.close();
sockServ.close();
}
catch (IOException ioe) {
System.err.println("Impossible to read from server!");
System.exit(1);
}
outClient.println(reply);
outClient.close();
try {
client.close();
}
catch (IOException ioe) {
System.err.printf("Impossible to close connection with %s:%d\n", client.getInetAddress().toString(), client.getPort());
}
}
}
}
UPDATE:
It seems that if I do:
boolean res = inServer.ready();
it always return false.
So Server is not ready to send the reply but this is strange...with my Project in C e Python it worked immediately. Why should java be different?
When you close outServer, you close the underlying socket. if you just want to close the output and keep the input open, you need to use Socket.shutdownOutput(). note, you have the same problem when you close inClient.
This works, maybe you can get some ideas from it...
ChatServer - broadcasts to all connected clients
In one command prompt: java ChartServer
In another: java ChatClient localhost (or the ip address of where the server is running)
And another: java ChatClient localhost (or the ip address of where the server is running)
Start chatting in the client windows.
Server like this...
// xagyg wrote this, but you can copy it
import java.io.*;
import java.net.*;
import java.util.*;
public class ChatServer {
public static List list = new ArrayList();
public static void main(String[] args) throws Exception {
ServerSocket svr = new ServerSocket(4444);
System.out.println("Chat Server started!");
while (true) {
try {
Socket s = svr.accept();
synchronized(list) {
list.add(s);
}
new Handler(s, list).start();
}
catch (IOException e) {
// print out the error, but continue!
System.err.println(e);
}
}
}
}
class Handler extends Thread {
private Socket s;
private String ipaddress;
private List list;
Handler (Socket s, List list) throws Exception {
this.s = s;
ipaddress = s.getInetAddress().toString();
this.list = list;
}
public void run () {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(s.getInputStream()));
String message;
//MyDialog x = (MyDialog)map.get(ipaddress.substring(1));
while ((message = reader.readLine()) != null) {
if (message.equals("quit")) {
synchronized(list) {
list.remove(s);
}
break;
}
synchronized(list) {
for (Object object: list) {
Socket socket = (Socket)object;
if (socket==s) continue;
PrintWriter writer = new PrintWriter(socket.getOutputStream());
writer.println(ipaddress + ": " + message);
writer.flush();
}
}
}
try { reader.close(); } catch (Exception e) {}
}
catch (Exception e) {
System.err.println(e);
}
}
}
Client like this ...
// xagyg wrote this, but you can copy it
import java.util.*;
import java.io.*;
import java.net.*;
public class ChatClient {
public static void main(String[] args) throws Exception {
Socket s = new Socket(args[0], 4444);
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintWriter out = new PrintWriter(s.getOutputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String message;
new SocketReader(in).start();
while ((message = reader.readLine())!=null) {
out.println(message);
out.flush();
if (message.equals("quit")) break;
}
in.close();
out.close();
}
}
class SocketReader extends Thread {
BufferedReader in;
public SocketReader(BufferedReader in) {
this.in = in;
}
public void run() {
String message;
try {
while ((message = in.readLine())!=null) {
System.out.println(message);
}
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
}