I have a server socket connection in a Java application. I have it connected to a client socket connection in a matlab script. I can get it to work fine if I start the server then start the client. But if I disconnect the client and try to start the client again it won't reconnect. How can I detect a disconnection on the socket on the server side, in order to reset the connections.
Server Side (Java)
boolean ss = false;
while(true){
try{
ServerSocket listener = new ServerSocket(9090);
Socket socket = listener.accept();
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
while(!ss){
if (files != null){
for( int i = 0; i < files.length; i++ )
{
out.println(files[i].getCanonicalPath());
}
files = null;
}
ss = out.checkError();
}
}
catch( IOException e)
{}
finally{
listener.close();
socket.close();
}
}
client side (matlab)
function filenameclient
tcpipClient = tcpip('127.0.0.1',9090,'NetworkRole','Client');
set(tcpipClient,'InputBufferSize',7688);
set(tcpipClient,'Timeout',30);
fopen(tcpipClient);
while(1)
if (tcpipClient.BytesAvailable > 0)
rawData = fread(tcpipClient,tcpipClient.BytesAvailable);
fprintf('FileName: %s\n',rawData);
end
end
fclose(tcpipClient);
end
I know the fclose never gets called, but I call it from the console after the stop the matlab client.
Related
I've a client-server connection. The client sends out request to server in a predefined format to initiate some processing at server. Server does this processing and then returns the result in predefined format to client.
Processing at server may take upto 15 mins.
I'm using reqObject.toString() to convert the request/response to string and then send through network using readUTF and writeUTF (reading the whole buffer).
Now the issue:
Data send by client is received properly and the processing happens. Once that is done, if the processing takes LESSTHAN 5 mins, once server sends the data, client receives it normally.
But if processing takes MORETHAN 5-6 mins, server sends back data, but client doesnt receive it (times out after given timeout period).
Code snippet:
Client:
Socket server = null;
OutputStream outToServer = null;
DataOutputStream out = null;
InputStream inFromServer = null;
DataInputStream in = null;
if(msg != null){
try
{
server = new Socket(serverIp, serverPort);
server.setSoTimeout(1000 * 60 * timeoutInMins); //set to 30 mins
outToServer = server.getOutputStream();
out = new DataOutputStream(outToServer);
out.writeUTF(msg);
out.flush();
// now wait for Server reply
inFromServer = server.getInputStream();
in = new DataInputStream(inFromServer);
responseString = in.readUTF();
// do something with response
}
Server:
ServerSocket serverSocket = null;
Socket client = null;
try{
serverSocket = new ServerSocket(port);
} catch (Exception e) {//log this}
try
{
while(true)
{
client = serverSocket.accept();
if(client.getRemoteSocketAddress() != null){
try{
ReqObject request = getRequest(client);
// do processing. this may take upto 10-15 mins at max
sendBackResponse(client, request);
}
// do remaining
private void sendBackResponse(Socket client, ReqObject result) throws IOException {
DataOutputStream out = null;
try{
out = new DataOutputStream(client.getOutputStream());
String outToClient = result.toString();
out.writeUTF(outToClient);
out.flush();
} finally {
try{out.close();}catch(IOException e){}
}
}
private ReqObject getRequest(Socket client) throws IOException {
DataInputStream in = null;
in = new DataInputStream(client.getInputStream());
String incoming = in.readUTF();
return convertMessageToRequest(incoming);
}
The connection was getting disconnected/blocked by a firewall which was in between, after 5 mins of inactivity.
To overcome this, I started sending heartbeat message (with junk data) every 2 minute. This kept the connection alive till the operation completed.
Note: The keepalive() method provided by java didn't help..
I have a simple echo-server in Java:
int portNumber = 4444;
try (
ServerSocket serverSocket =
new ServerSocket(Integer.parseInt(args[0]));
Socket clientSocket = serverSocket.accept();
PrintWriter out =
new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
) {
String inputLine;
while ((inputLine = in.readLine()) != null) {
out.println(inputLine);
System.out.println(inputLine);
}
} catch (IOException e) {
System.out.println("Exception caught when trying to listen on port "
+ portNumber + " or listening for a connection");
System.out.println(e.getMessage());
}
and a simple golang client:
func main() {
fmt.Println("start client")
conn, err := net.Dial("tcp", "localhost:4444")
if err != nil {
log.Fatal("Connection error", err)
}
conn.Write([]byte("hello world"))
conn.Close()
fmt.Println("done")
}
When I start the server and then run the client, the server echo's "hello world" as expected but then the server exits/terminates.
Q. How do I prevent this Java termination and force the server to continually wait for more client requests?
When the client terminates, the readLine on server side will result in the end of the stream. So if you want the server to continuously listen for new connections the simply put the above server code in a endless loop.
e.g.
while (true) {
// above code
}
For a play application that would be adequate.
I've been working on a simple Android TCP Server, so I can connect from a TCP Client and pass data back and forth.
I am encountering an weird problem, my android phone creates the TCP Socket, and I am able to connect to it via Hercules utility (A TCP client). The connection goes through, however the program is still blocking at the ServerSocket.accept() method.
Could anyone shed some light on this issue? Here is my java function.
public void TcpServer()
{
try
{
Socket s = null;
ServerSocket ss = null;
System.out.println("TCP Server Starting");
ss = new ServerSocket(27015);
s = ss.accept();
System.out.println("New connection! Yay");
BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream()));
String incomingMsg = input.readLine();
System.out.println("Received: " + incomingMsg);
}
catch (Exception e)
{
}
}
I am building a small chat application in which client A wants to send something to client C with server B in between. First of all is this a correct approach for the problem??. I am able to send and receive data to and from a server but it is limited to only the client.For example if Client A sends data to server B and client C is sending data to server B then i can send data back to A and C just like an echo server. But what i want is to forward data coming from Client A to Client C via server B.
The following is the server code:
public class Server {
public static void main(String[] args) {
int port = 666; //random port number
try {
ServerSocket ss = new ServerSocket(port);
System.out.println("Waiting for a client....");
System.out.println("Got a client :) ... Finally, someone saw me through all the cover!");
System.out.println();
while(true) {
Socket socket = ss.accept();
SSocket sSocket = new SSocket(socket);
Thread t = new Thread(sSocket);
t.start();
System.out.println("Socket Stack Size-----"+socketMap.size());
}
}
catch (Exception e) { }
}
}
class SSocket implements Runnable {
private Socket socket;
public SSocket(Socket socket) {
this.socket = socket;
}
#Override
public void run() {
try {
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
DataInputStream dIn = new DataInputStream(in);
DataOutputStream dOut = new DataOutputStream(out);
String line = null;
while (true) {
line = dIn.readUTF();
System.out.println("Recievd the line----" + line);
dOut.writeUTF(line + " Comming back from the server");
dOut.flush();
System.out.println("waiting for the next line....");
}
}
catch (Exception e) { }
}
}
The client code is :
public class Client {
public static void main(String[] args) {
int serverPort = 666;
try {
InetAddress inetAdd = InetAddress.getByName("127.0.0.1");
Socket socket = new Socket(inetAdd, serverPort);
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
DataInputStream dIn = new DataInputStream(in);
DataOutputStream dOut = new DataOutputStream(out);
BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Type in something and press enter. Will send it to the server and tell ya what it thinks.");
System.out.println();
String line = null;
while (true) {
line = keyboard.readLine();
System.out.println("Wrinting Something on the server");
dOut.writeUTF(line);
dOut.flush();
line = dIn.readUTF();
System.out.println("Line Sent back by the server---" + line);
}
}
catch (Exception e) { }
}
}
When your clients connect to the server, your server creates a Socket for it, here it is Socket socket = ss.accept();, your socket variable will be holding that client.
now if you just keep adding your client socket to a arraylist in your while loop, you will have a list of clients actively connected with your server like:
after the accept:
clients = new ArrayList<DataOutputStream>();
Socket socket = ss.accept();
os = new DataOutputStream(socket.getOutputStream());
clients.add(os);
Now as you have all the clients in that clients arraylist, you can loop through it, or with some protocol define which client should i send the data after reading.
Iterator<DataOutputStream> it = clients.iterator();
while ((message = reader.readLine()) != null) { //reading
while (it.hasNext()) {
try {
DataOutputStream oss = it.next();
oss.write(message);//writing
oss.flush();
}
catch (Exception e) { }
}
}
This will loop through all the available clients in the arraylist and will send to all. you can define ways to send to only some.
For example:
maintain a ActiveClients arraylist and with some GUI interaction may be or maybe, define what all clients you want to send the message.
Then add just those clients outputStreams to ActiveClients
ActiveClients.add(clients.get(2));
or remove them, if you don't want them.
ActiveClients.remove(clients.get(2));
and now just loop through this arraylist to send the data as above.
You can create message queue for each client:
Client A sends message 'Hi' with address Client C to server B.
Server B receives message and adds it to message queue of client C.
Thread in server B which communicates with client C check message queue, retrieve message and sends it to client C.
Client C receives message.
If I am not mistaken, you must be having a problem with receiving a message from the Server or SSocket class. What happens with your code is that when you send a message from the client to the server the Server class receives your messages also gives an echo of the message in the client. However, when you send a message from the Server class, you don't get any messages in the Client Class.
To get this to work, you would have to modify your code in the following fashion:
SSocket Class
String line = null;
while (true) {
line = dIn.readUTF();
System.out.println("Recievd the line----" + line);
dOut.writeUTF(line + " Comming back from the server");
dOut.flush();
System.out.println("waiting for the next line....");
}
You should add these lines:
String Line2 = take.nextLine(); //The user types a message for the client
dOut.writeUTF(Line2 + " Comming back from the server"); //The message is sent to the client
Replace the while loop with this one and it will work fine.
while (true) {
line = dIn.readUTF(); //Takes the msg from the client
System.out.println("Recievd the line----" + line); //Prints the taken message
String Line2 = take.nextLine(); //The user types a message for the client
dOut.writeUTF(Line2 + " Comming back from the server"); //The message is sent to the client
dOut.flush();
System.out.println("waiting for the next line....");
}
i've a minimal server which wait until a client connect ,then he start a thread which will send a reply back to the client, the problem is the reply.
This is the code of the server:
int port = 1234;
ServerSocket servSock = null;
servSock = new ServerSocket(port);
while (true) {
Socket link = servSock.accept();
serverThread st = new serverThread(link);
st.start();
}
This is the code of the run() method of the thread,the one which send the answer back, sk is the socket "link" passed by parameter in the server code
public void run() {
String dato = "";
InputStream i = null;
try {
i = sk.getInputStream();
} catch (IOException ex) {
Logger.getLogger(serverThread.class.getName()).log(Level.SEVERE, null, ex);
}
Scanner input = new Scanner(i);
//i receive the data sent
while (input.hasNext()) {
dato += input.nextLine();
}
// then i send a reply
DataOutputStream outputStream=new DataOutputStream(sk.getOutputStream());
outputStream.writeInt(1);
outputStream.close();
Client side ( only the code which should receive the answer from the server) :
Socket link;
int valid = 0;
String url="localhost";
int port=1234;
link = new Socket(InetAddress.getByName(url), port);
//i've to send some data to the server
PrintWriter output = new PrintWriter(link.getOutputStream(), true);
String a = new String(Base64.encode(mex));
output.println(createXml(tag, a));
output.flush();
//then i need to receive an answer from the server
DataInputStream answerI = new DataInputStream(link.getInputStream());
while(answerI.available()!=0)// but answerI.available() is always equal 0
valid = answerI.readInt();
answerI.close();
output.close ();
link.close();
With this code the istruction valid = answerI.readInt(); is not reached.
Without the while cycle, the client freeze at line : valid = answerI.readInt();
Can anyone help me?
Thank you in advance
I'm guessing that the server is blocked in a call to input.hasNext(). This will return false when the socket is closed, and its InputStream returns -1 to signal the end of the stream. However, the socket is still open. The client can send another line; the Scanner is blocking to see what the client's next move will be.
There are ways to shutdown "half" of a socket, so that the server can tell that the client has closed its sending channel but can still receive a response.
However, this approach is complicated. I suggest a change to the protocol so that the server can determine when it is allowed to respond.
In this protocol you don't need the reply if it is always '1'. Just close the socket. The client should block in a read() which will return -1 when the server closes the socket.