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.
Related
I am trying to send data to one of my servers and receive an ACK back from it. However, the processing gets hung up when waiting for a response from the server. I know for a fact that there is a connection because I can see the data reaching the server. I also know that the server is outputting data correctly because my C# client is receiving data back from the server. I will note that this client is running on a centOS virtual machine. The server is a remote windows machine. I wouldn't imagine that there would be an issue due to the virtual environment because I am able to use an SNMP java client (SNMP4j package) to make calls to a remote server. I believe my server is outputting raw binary too, but I would expect to see some kind of output either way.
// A Java program for a Client
import java.net.*;
import java.io.*;
public class Client
{
// initialize socket and input output streams
private Socket socket = null;
private DataInputStream input = null;
private DataOutputStream out = null;
private DataInputStream serveroutput= null;
// constructor to put ip address and port
public Client(String address, int port)
{
// establish a connection
try
{
socket = new Socket(address, port);
System.out.println("Connected");
// takes input from terminal
input = new DataInputStream(System.in);
// sends output to the socket
out = new DataOutputStream(socket.getOutputStream());
serveroutput = new DataInputStream(socket.getInputStream());
}
catch(UnknownHostException u)
{
System.out.println(u);
}
catch(IOException i)
{
System.out.println(i);
}
// string to read message from input
String line = "";
// keep reading until "Over" is input
while (!line.equals("Over"))
{
try
{
line = input.readLine();
out.writeUTF(line);
System.out.println(serveroutput.readLine())
}
catch(IOException i)
{
System.out.println(i);
}
}
// close the connection
try
{
input.close();
out.close();
socket.close();
}
catch(IOException i)
{
System.out.println(i);
}
}
Could be great if you would share the otherside codes. (sorry cannot comment yet)
Try use something else over writeUTF(), simply maybe a PrintStream, as mentioned by #marquis-of-lorne (read|write)UTF may be confusing by the peer.
Also this might be a good practice to flush() out the output from both side when there is nothing else to send to make sure data is sent completely.
You may also try BufferedReader over InputDataStream as you are trying to read lines. readLine() from InputDataStream is deprecated.
I'm trying to send a message from my pc to the board, but the problem is I keep losing connection before I decide to send a message.
This is code from which I'm sending the message. I create a socket, connect to the board, and then wait for inputs from the Scanner object. When I get some input I send a message to the board.
CLIENT
Socket socket = new Socket();
socket.connect(new InetSocketAddress("192.168.4.1",3000));
Scanner in = new Scanner(System.in);
String message = DataProtocol.sendMessageFormat("KLASA","METHOD","FILIP CACIC");
String message1 = DataProtocol.sendMessageFormat("KLASA","METHOD","FILIP CACIC");
message = message1 + message;
OutputStream outputStream = socket.getOutputStream();
String line;
while(!(line = in.nextLine()).equals("EXIT")){
outputStream.write(message.getBytes());
outputStream.flush();
}
This is code that is recv.message.
SERVER
void CommunicationProcessor::readFromStream(WiFiClient* wifiClient){
CLIENT_ACTIVE = true;
while(CLIENT_ACTIVE){
Serial.println(wifiClient->connected()); -> returns 1
int bytesRead = wifiClient->readBytes(buffer,1024); -> returns 0
Serial.println(wifiClient->connected()); -> returns 0
dataManager.appendData(bufferReader.getDataReaded(buffer,bytesRead));
if (checkIfEndLine(bytesRead)){
handleDataRecv();
dataManager.clearBuffer();
}
}
Serial.println("CLIENT QUIT");
}
Before method readBytes, I call method connected() and it returns 1. So everything is fine.
Method readBytes returns 0, because I did not yet send any message.
After that, I call connected() one more time and this time it returns 0.
Now if I remove this Scanner object and loop from code and send a message immediately, a server will recv. message.
Socket socket = new Socket();
socket.connect(new InetSocketAddress("192.168.4.1",3000));
Scanner in = new Scanner(System.in);
String message = DataProtocol.sendMessageFormat("KLASA","METHOD","FILIP CACIC");
String message1 = DataProtocol.sendMessageFormat("KLASA","METHOD","FILIP CACIC");
message = message1 + message;
OutputStream outputStream = socket.getOutputStream();
outputStream.write(message.getBytes());
outputStream.close();
My questions are why is connection closed after I call method readBytes?
EDIT
I just tested with this code and connection still get lost.
Line "Client alive" only gets printed one time.
SERVER
void loop(){
delay(1000);
if (client){
Serial.println("Client alive");
Serial.println(client.connected());
}else{
client = server.available();
if (client){
Serial.println(client.connected());
}
}
}
EDIT 2
I found the problem. I was using board as WIFI-ACCESS POINT, but when I connected board to my router and my pc, everything works fine.
So now my questions is why am I losing connection when board is configured as ACCESS-POINT?
EDIT 3
I found what was causing the problem. I had problem with connecting to wifi access point so i called method WIFI.persistent(false) and that was causing Broken Pipe exception (stream closed) in java.
I am writing Socket program , Here Client Sends a String through Stream , Server Process it and writes back to Client. My problem is, after Server process the String , it Writes back to Stream but in client It can't able to read the Stream its showing exception as Exception in while: java.net.SocketException: socket closed Here is my code,
Client ,
public void run() {
while (true) {
try {
// Open your connection to a server, at port 1231
s1 = new Socket("localhost", 1231);
OutputStream s1out = s1.getOutputStream();
DataOutputStream dos = new DataOutputStream(s1out);
InputStream in=s1.getInputStream();
DataInputStream dis=new DataInputStream(in);
String s = br.readLine();
dos.writeUTF(s);
dos.flush();
dos.close();
System.out.println(dis.readUTF());//it is the String from Server after processing
dis.close();
} catch (IOException ex) {
// Logger.getLogger(SimpleClient.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("Exception in while: " + ex);
}
}
In Server
public void run()
{
while(true){
try {
System.out.println("Waiting for connect to client");
s1=serverSocket.accept();
s1In = s1.getInputStream();
dis = new DataInputStream(s1In);
out=s1.getOutputStream();
dos=new DataOutputStream(out);
String clientData=dis.readUTF();
//processing task String
dos.writeUTF("Bus Registered Successfully");
dos.flush();
}
}
Here I am not able to read Bus Registered Successfully at client side . How to Solve this.?
Well there are many things not right in your program. But first let me answer your question ... you are closing the socket just after writing the stream ... so server throws exception, just remove dos.close(); just after the dos.flush();. It will run fine.
Now back to the programming practices ...
1) Server should accept the connection in a while(true) loop and then make a new thread. So following statement should not be the part of run method.
System.out.println("Waiting for connect to client");
s1=serverSocket.accept();
s1In = s1.getInputStream();
dis = new DataInputStream(s1In);
out=s1.getOutputStream();
dos=new DataOutputStream(out);
2) There is no need of run method in client. Because Every new client will be a new program that has its own variables and socket.
A quick look shows me that the reason the socket is closed is because you used dos.close().
Closing a DataInputStream (or PrintStream, or any similiar stream) will close the underlying socket.
Just take out dos.close().
You can also move the dos.close() to the very end of the try block. As a general rule, don't close anything related to the socket until you're done with the socket.
try {
Scanner inConsole = new Scanner(System.in);
String CONNECT_TO_WHOM = "";
Socket clientEndPoint = new Socket("localhost", 9000);
PrintWriter out = new PrintWriter(clientEndPoint.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(clientEndPoint.getInputStream()));
MessageFromServerThread messageFromServer = new MessageFromServerThread(in);
messageFromServer.start();
// Giving Client Details To whom To Connect
if(!in.ready())
CONNECT_TO_WHOM = inConsole.nextLine();
//System.out.println("You are Connecting To This " + CONNECT_TO_WHOM);
out.println(CONNECT_TO_WHOM);
//break;
System.out.println("To quit press q");
//inConsole.nextLine();
while(!clientMessage.equals("q")) {
out.println(clientMessage = inConsole.nextLine());
//System.out.println(in.readLine());
}
System.out.println("Check in chatClient");
} catch(Exception e) {
e.printStackTrace();
}
The code working flow:
Whenever client gets connected it the server, server will inform the client about all the other available clients, Then the from the client, server expects to which client to connect.
Here, there is a possibility that the client can be connected to another client before he wants to communicate with others. In that case the server informs that you are connected to Client X. I want to check this incident occurrence, via the if(!in.ready()).
I do understand that the in buffer could very well be empty. any way to effectively do this checking.
The java.io.BufferedReader.ready() method informs whether the stream
is ready to be read. A buffered character stream is only ready when
the buffer is not empty or if the underlying stream is ready.
So your buffer should be empty to make it return false condition
I have the code below:
while (true)
{
lengthInput = instr.readByte();
// Other code
}
The thing is that I'm using a client to send information to the socket, but after it finishes I got EOF Exception and it brokes the thread, what I need is to manages this and dont stop the thread, because I need to send more information and be able to read it.
Thanks in advance for your help.
I guess the problem is related to your socket initialization. You probably need to check if your client socket indeed successfully create a socket and bind to a specified port. You may also check your client really send data to the outstream and flush to the server side. I have a small project on Android emulators with socket communication. Both my client and serve extends from Java Thread class. Maybe you can gain some idea seeing my code below.
The client side
try {
socket = new Socket(InetAddress.getByAddress(new byte[]{10, 0, 2, 2}),
Integer.parseInt(remote_port));//note we must keep the addr#10.0.2.2
// write out
out = new ObjectOutputStream(socket.getOutputStream());
out.writeObject(out_msg);
out.flush();
// read in
in = new ObjectInputStream(socket.getInputStream());
socket.setSoTimeout(1000);
in_msg.set_message((Message)in.readObject());
// close all
out.close();
in.close();
socket.close();
return true;
}catch(InterruptedIOException E){}
The server side
while (true) {
try {
// read in message
Socket ClientSocket = serverSocket.accept();
Message out_msg = new Message();
// read in message
ObjectInputStream in = new ObjectInputStream(ClientSocket.getInputStream());
Message in_msg = (Message) in.readObject();
//Log.d(TAG, "recv" + " content:" + in_msg.msg2Str());
message_process(in_msg, out_msg);
// write out message
ObjectOutputStream out = new ObjectOutputStream(ClientSocket.getOutputStream());
out.writeObject(out_msg);
out.flush();
} catch(Exception E){}
}