Server accepts multiple connections using threads.
Server:
#Override
public void run () {
try {
System.out.println(client);
System.out.println("Client Connected");
//So far, so good. Client is connected
BufferedReader in = new BufferedReader(
new InputStreamReader(this.client.getInputStream()));
System.out.println(in.readLine());
// Nothing happens
} catch (Exception e) {
e.printStackTrace();
}
}
Client:
try {
PrintWriter out = new PrintWriter(Client.socket.getOutputStream());
BufferedReader in = new BufferedReader (
new InputStreamReader(Client.socket.getInputStream()));
out.write("Information sent from client");
// Does not work
in.read();
// Before this .read it would give a "Connection reset" probably
// Because the client closed before the server could even read
}
No error, but it just hangs, nothing is being sent. Firewall is down so it can't be that. Also it used to work yesterday. I have no idea what I could have messed up.
write writes the content only to the InputStream. Use println to send an additional newline character to correspond to the readLine statement on the server.
out.println("Information sent from client");
Related
I want to send an object from my client to my localhost server to add to database, and send result back whether the object was sent successfully or not. The object was sent successfully, but my server doesn't send the result back to client, and causes my client frame form hanged due to waiting for response from server. I don't know what's wrong with my code. Can you tell me some ways to fix this?
Here is the function to send the result:
public void sendResult(String result) {
try {
Socket clientSocket = myServer.accept();
System.out.println("Connected to client");
ObjectOutputStream os = new ObjectOutputStream(clientSocket.getOutputStream());
os.writeObject(result);
System.out.println("Result sent");
} catch (Exception ex) {
ex.printStackTrace();
}
}
Where the send result function is called:
public void service() {
try {
if (receiveStudent() != null) {
Student std = receiveStudent();
if (dao.addStudent(std)) {
System.out.println("OK");
sendResult("OK");
} else {
System.out.println("FAILED");
sendResult("FAILED");
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
In addition, in the Service function, the console printed "OK", which means the if condition was satisfied.
receive student method:
public Student receiveStudent() {
Student s = new Student();
try {
Socket clientSocket = myServer.accept();
System.out.println("Connect to client successfully");
ObjectInputStream ois = new ObjectInputStream(clientSocket.getInputStream());
Object o = ois.readObject();
if (o instanceof Student) {
s = (Student) o;
return s;
}
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
Because of myServer.accept() in sendResult(), the server is again waiting for an incoming client connection while this already happened in receiveStudent(). Reuse that connection.
Share the client socket you've obtained in receiveStudent() by, e.g., turning it into a field.
public Student receiveStudent() {
...
try {
clientSocket = myServer.accept();
...
} catch (Exception ex) {
...
}
...
}
and then reuse that socket in sendResult() to send the result to the client.
public static void sendResult(String result) {
try {
...
ObjectOutputStream os = new ObjectOutputStream(clientSocket.getOutputStream());
...
} catch (Exception ex) {
...
}
}
If you want to send a String as object why don't you just use something like this:
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); //for sending String messages
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); //for getting String messages
... and then when you need to send you do it like this:
out.println(textToServer"); // send to server - don't forget LN in println.
out.flush(); // to clean buffer
It should do what you need to be done.
And make sure that your client class is waiting to get that InputStream you're sending, don't forget that, since maybe it's the problem in the Client side.
Maybe Client is not accepting that incoming Socket regardless if it's ObjectInputStream or BufferedReader that will accept the incoming socket object.
You could provide us a Client class so we can see if there's missing acceptance of incoming socket.
At the end of the method make sure you close your streams and sockets.
out.close();
in.close();
socket.close();
For more details check this, this and this. I hope I was helpful :)
You're calling accept() twice. This is meaningless. You need to:
Accept the connection. This returns a Socket.
Read the request and create the response.
Send the response, via the same Socket you accepted at (1).
You also want to create a new thread per accepted socket, and you also want to do all I/O in that thread, including creating the ObjectInputStream and ObjectOutputStream. Otherwise your server isn't properly multi-threaded and multi-client.
I'm developing an application that can control mouse from android phone. The problem is communication is very slow with socket mouse lags while moving. I want to move mouse pointer as the user moves his finger on screen. How can I optimize this code?
On computer side I'm using this code
try {
serverSocket = new ServerSocket(4444);
} catch (IOException e) {
System.out.println("Could not listen on port: 4444");
}
System.out.println("Server started. Listening to the port 4444");
while (true) {
try {
clientSocket = serverSocket.accept();
inputStreamReader = new InputStreamReader(
clientSocket.getInputStream());
bufferedReader = new BufferedReader(inputStreamReader);
message = bufferedReader.readLine();
System.out.println(message);
Robot robot = new Robot();
switch (message) {
case "first":
ix = MouseInfo.getPointerInfo().getLocation().x;
iy = MouseInfo.getPointerInfo().getLocation().y;
break;
case "lclickp":
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
break;
case "lclickr":
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
break;
//several more cases
} catch (IOException | AWTException ex) {
System.out.println("Problem in message reading");
}
and I'm using this on android side.
private class SendMessage extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
try {
client = new Socket(Login.IP, 4444); // connect to the server
printwriter = new PrintWriter(client.getOutputStream(), true);
printwriter.write(messsage); // write the message to output stream
printwriter.flush();
printwriter.close();
client.close(); // closing the connection
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
Don't create a new connection per message: keep the socket open. At the server end, process multiple messages per accepted socket, until readLine() returns null.
Now I just beginning learning and I'm not good in socket programming but I think the server should wait for new connections in a separate thread because the ServerSocket.accept() method blocks until there is a connection and causes my app frozen at that line.
Thread conWaitingThread = new Thread(new Runnable(){
while (true){
//try
socket = serverSocket.accept();
//catch
}
void startWaiting(){
comWaitingThread.start();
}
void endWaiting(){
if(conWaitingThread.isAlive()){
conWaitingThread.interrupt();
}
}
and for reading msg from client,
while(input.readLine()!=null){
try{
message = input.readLine();
//ur switch case
}catch (ioException e){
//do catch
}
}
For client side, create socket and iostreams once and let them open. Not close the iostreams as closing iostreams closes the respective socket too. May open socket and io in onCreate and close in onDestroy. Be aware that input.readLine() on serverSide waits the new line char and printWriter.write() does not automatically add that. So you may not get any incoming data although printWriter.flush() is called and you need to concat "\n" on writing.
On the PC Side of things:
Consider refactoring into a few helper classes, perhaps, one for Connect, one for sending updates, and one for Disconnect. Then, you will only need to connect and disconnect once per session.
It's good practice to set a tick rate on both the server and client to prevent over-using CPU time and other resources. There is no need to update mouse coordinates more frequently than the refresh rate of typical monitor can update (60fps / 16.6ms) for example.
I have two problems with an app that i have built for socket communication, first I'll try to explain what the app does and then I'll go into the details of those two problems.
First I click on a button, which starts a thread, which sends a multicast massage "group address" through a UDP socket. Once any of the devices receive the massage, they will send a response through TCP socket and my device will act as a server to the one that sent the response. So after debugging I found out the first problem which is clientSocket = serverSocket.accept(); sometimes gets stuck and the app will block everything and keep executing it, which might happen because the udp massage might never arrive at the destination which means there is no client for the tcp server that I've created.
First question: Is there any way to make the serverSocket.accept(); non-blocking or set a time out? I've tried serverSocket.setTimeSoOut() method, but that didn't work. Maybe this problem comes from something other than the UDP message?
The second problem is that if I press the button that calls the thread twice it will throw a BindException address already in use: Which will happen because of the re execution of serverSocket.bind(new InetSocketAddress(4125));. Is there any way to fix/avoid that?
Here are the threads that I'm using:
This one is called after I press the button:
private class ChatClientThread extends Thread {
DatagramSocket socket;
String sentence;
String modifiedSentence;
BufferedReader inFromUser;
DataOutputStream outToServer;
BufferedReader inFromServer;
Socket clientSocket;
ServerSocket serverSocket;
#Override
public void run() {
/*Socket socket = null;
DataOutputStream dataOutputStream = null;
DataInputStream dataInputStream=null;*/
clientSocket=null;
try {
String data="NewTask_"+EmpPhoneNumber;
serverSocket=new ServerSocket();
serverSocket.setReuseAddress(true);
serverSocket.bind(new InetSocketAddress(4125));
socket = new DatagramSocket(52276);
socket.setBroadcast(true);
InetAddress group = InetAddress.getByName(
"224.0.1.2");
DatagramPacket packet = new DatagramPacket(data.getBytes(), data.length(),
group, 52276);
socket.send(packet);
while(true){
clientSocket = serverSocket.accept();
ConnectThread ct=new ConnectThread(clientSocket);
ct.start();
}
} catch (UnknownHostException e) {
e.printStackTrace();
final String eString = e.toString();
TicketDetails.this.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(TicketDetails.this, eString, Toast.LENGTH_LONG).show();
}
});
} catch (IOException e) {
e.printStackTrace();
final String eString = e.toString();
TicketDetails.this.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(TicketDetails.this, eString, Toast.LENGTH_LONG).show();
}
});
} finally {
TicketDetails.this.runOnUiThread(new Runnable() {
#Override
public void run() {
}
});
}
}
}
this one is called from the above thread as you can see:
private class ConnectThread extends Thread {
Socket socket;
String sentence;
String modifiedSentence;
BufferedReader inFromUser;
DataOutputStream outToServer;
BufferedReader inFromServer;
ConnectThread(Socket socket){
this.socket= socket;
}
#Override
public void run() {
DataInputStream dataInputStream = null;
DataOutputStream dataOutputStream = null;
Socket socket2 = null;
DataOutputStream dataOutputStream2= null;
DataInputStream dataInputStream2=null;
try {
while(true){
inFromUser = new BufferedReader( new InputStreamReader(System.in));
outToServer = new DataOutputStream(socket.getOutputStream());
inFromServer = new BufferedReader(new InputStreamReader(socket.getInputStream()));
sentence = inFromUser.readLine();
modifiedSentence = inFromServer.readLine();
socket2 = new Socket(socket.getInetAddress().getHostAddress(), 4125);
dataOutputStream2 = new DataOutputStream(
socket2.getOutputStream());
String[] parts = modifiedSentence.split("_");
String partGive = parts[0].substring(4); // 004
String partEmpId = parts[1];
if(partGive.equals("GiveMeATask")&&Integer.parseInt(partEmpId)==empId){
dataOutputStream2.writeUTF(" "+"SolveProblemOrder_2");
dataOutputStream2.flush();
}
System.out.println("FROM SERVER: " + modifiedSentence);
if(modifiedSentence!=null) break;}
outToServer.close();
inFromServer.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (dataInputStream != null) {
try {
dataInputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (dataOutputStream != null) {
try {
dataOutputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
Those are two very commmon problems. I'll answer the two in reverse order.
The button you are talking about is creating a ServerSocket and binding it to a specific port. In your case, the port is 4125. From looking at your code, you don't seem to be closing that serversocket anywhere. When you click the button a second time, a second instance of ServerSocket tries to bind to the same port - but that port is still in use by the first ServerSocket. In that case, you get a bind exception. One port cannot be used by more than one ServerSocket. The solution would be to close the existing ServerSocket before creating a new one using serverSocket.close();
If you read the documentation, it clearly states what ServerSocket.accept() does: "[...] The method blocks until a connection is made." This is the "getting stuck" that you described. The thread that executes that code is put into a waiting position and continues only when a connection is made, then returns that new connection. The classic approach is to start a new thread that waits for incoming connections so that your main thread continues to execute and your whole application does not "freeze". Another approach would be a non-blocking framework that encapsulates all that overhead away from you, one of those is Apache MINA.
I would highly suggest to look into small example projects that deal with basic client/server behaviour as you will most likely deal with threads here.
First problem: It is very likely that your application is not receiving the UDP packages. If serverSocket.accept() doesn't get any clients it'll wait indefinitely for someone to connect. You could avoid this by using yet another thread that just accepts connections to avoid freezing your application. Another way would be to use Java's NIO classes that provide non-blocking IO for pretty much anything. That would require you to use ServerSocketChannel and related classes. (Quick googling also gave me this guide which seems fairly easy to follow).
Second problem: You need to close your ServerSocket once you're done using it. Otherwise the port will never be free again to be used by another ServerSocket.
Alternatively you could just leave the Socket open and remember that you already openend it (e.g. with a boolean field in your class).
I am using a thread and a while true loop to listen for message from my server. For some strange reason some messages are getting lost. (I am logging from my server so i am 100% sure that the message is sent, therefore the problem has to be on the client side). This seems to happend when the server is sending messages fast to the client.
Im using the following code to listen for new messages (on my client):
Socket socket;
try {
socket = new Socket(InetAddress.getByName("url.com"), 8080);
is = new DataInputStream(socket.getInputStream());
os = new DataOutputStream(socket.getOutputStream());
} catch (IOException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
JOptionPane.showMessageDialog(rootPane,
"Could not establish network connection to the server."
+ " \nPlease check your internet connection and restart the application.",
"Unable to connect",
JOptionPane.INFORMATION_MESSAGE);
WindowEvent wev = new WindowEvent(this, WindowEvent.WINDOW_CLOSING);
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(wev);
setVisible(false);
dispose();
System.exit(0);
}
// Starta thread to listen for messages from the server
new ListenFromServer().start();
/*
* Thread class to listen for message from the server
*/
class ListenFromServer extends Thread {
public void run() {
while (true) {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(is));
String tmpMsg = in.readLine().replaceAll("\\r\\n|\\r|\\n", "");
JSONObject json = new JSONObject(tmpMsg);
if(json.get("type").toString().contains("preview")) {
System.out.println("PREVIEW: " + json.get("msg").toString());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
You shouldn't be creating a new BufferedReader to receive each message. If two messages arrive in quick succession, it could pull multiple messages out of is, and then you're discarding the contents. Declare in outside of your while loop (and handle the close condition appropriately).
I think what you want is a ServerSocket -- it listens and handles a queue of incoming connections (default size 50) so that you don't lose connections. As your code is, if a connection is attempted in the time between one connection getting established and the loop coming around to connect() again, there wouldn't be anything listening.
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I've a task here and I am unable to finalize and not sure what technology opt my problem. Here is the explanation of my problem. My application is stand alone application and will deploy in different locations. Lets say LocA, LocB and so on. Each location has its own clients some clients are connected via LAN and some are third party clients. As long as if the clients are connected via LAN no problem of requesting and response. But there will be few clients which are not connected via LAN.
To the third party clients we will provide IP and PORT to connect and request for data in a standard HL7 format. The problem here is the clients can create their own client program by using any technology. They may use Socket programming, .NET socket programming and so on. But our server should accept connections from clients what ever the technology it is, process their requests and respond back to them. And the requirement is the server program should run always and listens to the allotted ports or whenever there is a request to specific port then start our server program and process the client request and respond back to client.
Please pardon me if my English confuses you. Please give me a solution for my problem.
Note : Client program can be any technology and any programming language. That is up to client which way they want to use to connect with server and send their requests.
I am giving a small example here, that how client and server works with Socket, i am also including the multithreading on the Server side.
Client side code:
public class ClientWala {
public static void main(String[] args) throws Exception{
Boolean b = true;
Socket s = new Socket("127.0.0.1", 4444);
System.out.println("connected: "+s.isConnected());
OutputStream output = s.getOutputStream();
PrintWriter pw = new PrintWriter(output,true);
// to write data to server
while(b){
if (!b){
System.exit(0);
}
else {
pw.write(new Scanner(System.in).nextLine());
}
}
// to read data from server
InputStream input = s.getInputStream();
InputStreamReader isr = new InputStreamReader(input);
BufferedReader br = new BufferedReader(isr);
String data = null;
while ((data = br.readLine())!=null){
// Print it using sysout, or do whatever you want with the incoming data from server
}
}
}
Server side code:
import java.io.*
import java.net.*;
public class ServerTest {
ServerSocket s;
public void go() {
try {
s = new ServerSocket(44457);
while (true) {
Socket incoming = s.accept();
Thread t = new Thread(new MyCon(incoming));
t.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
class MyCon implements Runnable {
Socket incoming;
public MyCon(Socket incoming) {
this.incoming = incoming;
}
#Override
public void run() {
try {
PrintWriter pw = new PrintWriter(incoming.getOutputStream(),
true);
InputStreamReader isr = new InputStreamReader(
incoming.getInputStream());
BufferedReader br = new BufferedReader(isr);
String inp = null;
boolean isDone = true;
System.out.println("TYPE : BYE");
System.out.println();
while (isDone && ((inp = br.readLine()) != null)) {
System.out.println(inp);
if (inp.trim().equals("BYE")) {
System.out
.println("THANKS FOR CONNECTING...Bye for now");
isDone = false;
s.close();
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
try {
s.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new ServerTest().go();
}
}
Use a TCP socket connection with a serialized object that gets passed between the client and the server. This is required otherwise the infromation being transfered over will be lost in translation. Using this method, you must provide the client with the requirements (the serialized object) so the programs can communicate with each other. If you use (coming from java) a socket connection, it will be able to accept any incoming TCP connection on the port.
Here is a good idea of what I'm referring to
try
{
socket = new ServerSocket(portnum);
}
catch (IOException ioe)
{
output.append("IOException getting server socket\n" + ioe + "\n");
return;
}
while (true)
{
try
{
client = socket.accept();
output.append("Connected to client at " + client.getInetAddress());
clientHandler(client);
}
catch (IOException ioe)
{
output.append("IOException during accept \n " + ioe + "\n");
return;
}
}
this will take any TCP connection request on port "portnum".
Make sure to multithread your application, or you won't be able to accept any connection requests while a connection is already established.
Seeing as you mentioned HL7, you should probably take a look at HAPI (http://hl7api.sourceforge.net/) It comes with extensive documentation, including this example for sending & receiving messages.
Note that as long as their implementations of HL7 are compatible, it doesn't matter what technology your client programs use. Also: sockets work just fine without LAN because 127.0.0.1 (the localhost address) is always available.