Having an issue with my input/output streams. Connecting a client to a server via SSL, and trying to send a message from the client to server.
However, when I write to my outputstream, nothing is read on the other end.
note - I am running my buffer in a separate thread called sendReceive, so that it does not block the main application while waiting for input. I pass it an input of SSLSocket, and it then establishes the corresponding streams/buffers. I'm not sure if this is where the issue lies in itself.
Here's the relevant part of my server.
static void initializeCLAConnection(){
try {
SSLServerSocketFactory sslserversocketfactory =
(SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
SSLServerSocket sslserversocket =
(SSLServerSocket) sslserversocketfactory.createServerSocket(3577);
SSLSocket sslsocket = (SSLSocket) sslserversocket.accept();
System.out.println("Connection accepted from: "+sslserversocket.getInetAddress());
//initialize buffer thread
sendReceive CLABuf = new sendReceive(sslsocket);
System.out.println("CLABuf established.");
CLABuf.start();
When CLABuf.start() is called, it runs the following thread. Here, it never reaches the print statement "Receiving input", regardless of how many times I write to the stream.
public class sendReceive extends Thread{
InputStream inputstream;
InputStreamReader inputstreamreader;
BufferedReader bufferedreader;
OutputStream outputstream;
OutputStreamWriter outputstreamwriter;
BufferedWriter bufferedwriter;
public sendReceive(SSLSocket socket) throws IOException{
inputstream = socket.getInputStream();
inputstreamreader = new InputStreamReader(inputstream);
bufferedreader = new BufferedReader(inputstreamreader);
outputstream = socket.getOutputStream();
outputstreamwriter = new OutputStreamWriter(outputstream);
bufferedwriter = new BufferedWriter(outputstreamwriter);
System.out.println("CLA Buf established in new thread");
}
#Override
public void run() {
//listen to inputstream
String string=null;
while(this.isAlive()){
System.out.println("Buf running");
try {
while((string=this.bufferedreader.readLine())!=null){
System.out.println("Thread receiving input!");
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
}
and the relevant part of my client sending the msg.
public void initializeVoterToCLA(){
try {
/*
* socket for Voter -> CLA
*/
SSLSocketFactory sslsocketfactoryCLA = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket sslsocketCLA = (SSLSocket) sslsocketfactoryCLA.createSocket("localhost", 3577);
InputStream inputstreamVoter = sslsocketCLA.getInputStream();
InputStreamReader inputstreamreaderVoter = new InputStreamReader(inputstreamVoter);
BufferedReader bufferedreaderVoter = new BufferedReader(inputstreamreaderVoter);
OutputStream outputstreamCLA = sslsocketCLA.getOutputStream();
OutputStreamWriter outputstreamwriterCLA = new OutputStreamWriter(outputstreamCLA);
BufferedWriter bufferedwriterCLA = new BufferedWriter(outputstreamwriterCLA);
//send msg
bufferedwriterCLA.write("test msg");
You're reading lines but you're not writing lines. Add a line terminator.
Nothing to do with SSL.
NB Testing this.isAlive() is futile. If it was false, the code that tests it wouldn't be running. This outer loop is completely pointless. Once the inner loop exits, there is nothing more to read. Just remove the outer loop.
Related
I'm able to send string to the server and server also received the same. Server is able to send the acknowledgment but client is not getting acknowledged until server ends the connection. But I don't want to close the connection. How should I display the acknowledgment without closing the connection?
//This is Client
public void Actuator1_Stop(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
Socket socket = new Socket("localhost", 1028);
DataOutputStream dout = new DataOutputStream(socket.getOutputStream());
dout.writeUTF("Stop_Actuator");
dout.flush();
System.out.println("Command Sent = Stop_Actuator");
//Get the return message from server
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String message = br.readLine();
System.out.println("ACK received from the server : " +message);
socket.close();
} catch(Exception exception) {
exception.printStackTrace();
}
}
//This is Server
class Socket4 implements Runnable {
public void run() {
try {
ServerSocket ss = new ServerSocket(1028);
while(true) {
Socket s = ss.accept();
DataInputStream dis = new DataInputStream(s.getInputStream());
String cmd = dis.readUTF();
System.out.println("Command= "+cmd);
//Sending the response back to the client
String ack = null;
OutputStream os = s.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
if(cmd.equals("Stop_Actuator")) {
ack= "Ok";
bw.write(ack);
} else {
ack = "Error";
bw.write(ack);
}
System.out.println("ACK sent to the client is "+ack);
bw.flush();
}
} catch(Exception e) {
e.printStackTrace();
}
}
}
public class MyServer {
public static void main(String[] args) {
Socket1 s1 = new Socket1();
Socket2 s2 = new Socket2();
Socket3 s3 = new Socket3();
Socket4 s4 = new Socket4();
Thread t1 = new Thread(s1);
Thread t2 = new Thread(s2);
Thread t3 = new Thread(s3);
Thread t4 = new Thread(s4);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
}
How should I display the acknowledgment without closing the connection?
In your client you are doing a read-line:
String message = br.readLine();
However from the server you are not sending a complete line. You need to add line termination characters to the end of the message:
ack = "Ok\n";
bw.write(ack);
The read-line then completes and the client gets the ack. Obviously the error ack also needs a newline ("Error\n").
Make sure that you are properly closing the accepted socket and the server socket that are created in Socket4.run(). I assume that you are just posting portions of your code but make sure to close those sockets in a try/finally blocks.
I am having problem even with this very basic client-server application. The client is not sending data/ the server is not receiving. I cannot understand where is the problem. I am even starting to think that i did not understand anything about sockets.
This is the Server code:
public class Server
{
public static void main(String args[])
{
try{
ServerSocket serverSocket = new ServerSocket(3000);
Socket socket = serverSocket.accept();
System.out.println("Client connected: "+socket.getInetAddress.toString());
Scanner scanner = new Scanner(socket.getInputStream());
while(true)
{
System.out.println(scanner.nextLine());
}
}catch(IOException e)
{
System.out.println("error");
}
}
}
This is the client code:
public class Client
{
public static void main(String args[])
{
Socket socket;
PrintWriter printWriter;
try {
socket = new Socket("127.0.0.1", 3000);
printWriter = new PrintWriter(socket.getOutputStream(), true);
while(true)
{
printWriter.write("frejwnnnnnnnnnnnnnnnnnnnnnnnnosfmxdawehtcielwhctowhg,vort,hyvorjtv,h");
printWriter.flush();
}
}catch(IOException e)
{
System.out.print("error\n");
}
}
}
If I run both on the same machine, the server prints correctly "client connected .....", but then prints no more.
What is the problem?
The server reads the next line. The client doesn't send any line ending. So the server can't possibly know that the line is supposed to be ended, and blocks until it finds an EOL in the stream. Or until the client closes its socket.
In client code, you decorate your output stream with PrintWriter, so you can use println.
Replace
printWriter.write("frejwnnnnn...rjtv,h");
printWriter.flush();
by:
printWriter.println("frejwnnnnn...rjtv,h");
Flush is useless since have request autoflush (true in PrintWriter constructor).
In server code, you can use a BuffererdReader decorator instead of Scanner:
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String inputLine;
while ((inputLine = br.readLine()) != null) {
System.out.println(inputLine);
}
i want to make communication between android device and java server.
Server side:
ServerSocket serverSocket = new ServerSocket(port);
Socket socket = serverSocket.accept();
OutputStream out = socket.getOutputStream();
PrintStream pw = new PrintStream(out);
pw.print("hello");
pw.flush();
socket.close();
Android client side :
public class connectTask extends Thread {
#Override
public void run() {
super.run();
while (true) {
try {
Socket socket = new Socket("192.168.0.101", 4444);
InputStream inputStream = socket.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String line = reader.readLine();
runOnUiThread(new Runnable() {
#Override
public void run() {
textView.setText(line);
}
});
socket.close();
} catch (IOException e) {
}}}}
and starting thread this way:
thread = new Thread(new connectTask());
thread.start();
the problem is I cannot get anything from java server. I either send or receive data wrong and i can't figure out what's the issue, what am I doing wrong here?
Your code looks good (may be String line = ... should be final String line = ...) and IP address and port of Server need to be checked.
Am I doing this right? When I try to run this on my computers loopback address I'm getting a "connection reset" error.
public class DateTimeClient {
public static void main(String[] args) throws IOException {
int port = Integer.parseInt(args[0]);
String host = args[1];
try {
System.out.println("Connecting....\n");
Socket socket = new Socket(host, port);
PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
BufferedReader reader = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
System.out.println("Date: " + reader.read());
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class DateTimeServer {
public static void main(String[] args) {
int portNum = Integer.parseInt(args[0]);
try {
ServerSocket socket = new ServerSocket(portNum);
Socket client = socket.accept();
BufferedReader reader = new BufferedReader(new InputStreamReader(
client.getInputStream()));
PrintWriter writer = new PrintWriter(client.getOutputStream());
Date date = new Date();
writer.print(date.toString());
} catch(Exception e) {
e.printStackTrace();
}
}
}
I grab the port to run the server on, the port to connect to and the host as arguments in the main method, create sockets and use BufferedReader and PrintWriter. I followed Oracle's tutorial on this pretty closely so I'm not sure where I coulda made a mistake.
#EJP is correct, but I think that the actual problem is that the server side is neither closing or flushing writer. When the server exits, the TCP/IP connection gets closed (by the server-side OS) without any data having been written to the socket. The client side JVM sees a reset connection and throws an exception.
Solution: Close your streams properly on the server side and the client side should see the data. (Flushing would work too ... but if you neglect to close the streams in all cases, you risk problems with server-side file descriptor leaks. Hence, closing is the best solution.)
You're only reading one character, not a date. Try sending and receiving a line.
I have this code:
Socket incomingConnection = serverSocket.accept();
String strategy = "1";
Client client = new Client(incomingConnection, this, strategy);
Constructor of Client:
public Client(Socket socket, ChatServer chatServer, String strategy) throws IOException{
this.socket = socket;
this.inputStream = socket.getInputStream();
this.outputStream = socket.getOutputStream();
this.chatServer = chatServer;
this.instance1 = new Strategy1(chatServer, this);
this.instance2 = new Strategy2(chatServer, this);
this.strategy = (this.instance1.getName().equals(strategy1) ? this.instance1 : this.instance2);
this.strategy.setStreams();
}
Now how looks like Strategy1:
public class Strategy1{
public Strategy1(ChatServer server, Client client) throws IOException{
this.chatServer = server;
this.client = client;
}
public void setStreams() throws IOException{
inputStream = new ObjectInputStream(client.getInputStream());
outputStream = new ObjectOutputStream(client.getOutputStream());
}
And the same Strategy2.
Method in Client class :
client.getInputStream() {
return inputStream;
}
// similar for outputStream
The problem is : when Client's constructor tries to execute strategy.setStreams(), the program blocks on new ObjectInputStream().
When I move setStream() method's containment into Constructor of Strategy1 then it works!
Why?
Swap these lines:
inputStream = new ObjectInputStream(client.getInputStream());
outputStream = new ObjectOutputStream(client.getOutputStream());
Creating an ObjectInputStream reads from the socket. If you create input streams first on both ends of the connection, it will deadlock. The safest is to always create output streams first.