Server program :
import java.io.*;
import java.net.*;
public class server
{
public static void main(String args[])
{
try
{
ServerSocket ss=new ServerSocket(2000);
Socket s=ss.accept();
BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream()));
String str;
while((str=br.readLine())!=null)
{
System.out.println(str);
}
}
catch(Exception e)
{
System.out.println(e);
}
}
}
Client program :
import java.net.*;
import java.io.*;
public class client
{
public static void main(String args[])
{
try
{
Socket s=new Socket("127.0.0.1",2000);
String str;
BufferedWriter br=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
br.write("\nHello World\n");
}
catch(Exception e)
{
System.out.println(e);
}
}
}
The issues that I am facing are:
No output.
No Exception/Error is indicated.
Please explain me if am doing anything wrong. The problem might be the client has not written anything while the server is reading.
Close the stream after writing to stream in client program
br.close();
After Writing to stream it is compulsory to close the stream or flush the stream(br.flush()) because when stream is closed then only that stream can be read.
I/O operations can not be performed on same stream simultaneously.
Two sockets are connected by same stream so I/O operations can not be performed simultaneously on that stream.
Please add some debug statement to check
(1) is client able to make the connection with running server or not. so in server part add
Socket s=ss.accept();
System.out.println("one new connection");
(2) also in client program add flush() after the br.write line
br.write("\nHello World\n");
br.flush()
// use the below statement as well at last (if you no longer want to use the output stream)
br.close();
Please note you are just write one time here.... for continuous reading and writing you will have to run this in loop....
OR
to run multiple clients simultaneously ... you will have to execute each socket connection (after accepting it) into different thread at server end
Related
I have a client program that sends messages typed in console to the server. Following some advices, I introduced a check for a closed socket with Socket.checkError(). Nevertheless, for some reason it indicates error only after second failed attempt to send a message.
My code:
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
while (true)
try (
Socket clientSocket = new Socket(hostname, port);
PrintWriter socketOut = new PrintWriter(clientSocket.getOutputStream(), true);
) {
String input;
while ((input=stdIn.readLine())!=null) {
socketOut.println(input);
if (socketOut.checkError()) {
System.out.println("Got socket error");
break;
}
}
} catch (IOException e) {
try {
Thread.sleep(5000);
} catch (InterruptedException e1) {}
}
I shut down (manually) my server side after receiving 'message1'. Therefore, I expect to get the error while trying to send the very next message. Nevertheless it occurs only one message after:
message1
message2
message3
Got socket error
Can anyone explain this behavior and advise me a method to get notification right on the first attempt to send a message in void?
Following some advices, I introduced a check for a closed socket with Socket.checkError().
There is no such method. Clearly you are referring to PrintWriter.checkError().
Nevertheless, for some reason it indicates error only after second failed attempt to send a message.
The reason is that there is both a socket send buffer at the sender and a socket receive buffer at the receiver, and that sending is asynchronous: it therefore isn't possible for the first send to detect an error.
Can anyone explain this behavior and advise me a method to get notification right on the first attempt to send a message in void?
There isn't one. That's the nature of TCP. What you are attempting indicates an application protocol error, and the answer lies in the realm of the application protocol as well: don't have the peer close the socket while this end could still be sending data, OR don't allow this end to send data after the peer has indicated, via the application protocol, that it won't be reading any more data.
Don't use PrintWriter over the network. It suppresses the actual exception. Use BufferedWriter and the write() and newLine() methods.
In ths java library there is no method to check if connection is opened or not. Method like isConnected() and isClosed() check only one side of the connection (where you invoked the method).
From javadoc:
Note: Closing a socket doesn't clear its connection state, which means
this method will return true for a closed socket (see isClosed()) if
it was successfuly connected prior to being closed.
To check if the connection has been really closed simply invoke the read() method (or equivalent) and check if it returns -1.
Note: also if isConnected will work as you like (giving false if the other side of the socket closed the connection or if there is a network problem or similar) the sequence:
if (socket.isConnected()) {
int x = socked.read();
}
will not grant that the x has a value different from -1 or throws an IOException, because the connection could be closed after the isConnected test and before the read operation.
The following code to show how any kind of check on the socket cannot guarantee that a subsequent read will give a valid result.
// Return true because socket communication is enabled
if (myFunctionToCheckIfSocketIsOpen(socket)) {
// Here the peer closed the socket or the network shutdown
// This read will give -1 or throws IOException also if the previous check returned true
int x = socket.read();
}
From the answer of #Davide Lorenzo MARINO I got the idea of employing read(). The only problem that it is blocking. However, one can always run it in another thread, which would modify a class global variable, when read() finally returns -1:
static boolean socketIsAlive;
...
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
while (true)
try (
Socket clientSocket = new Socket(hostname, port);
PrintWriter socketOut = new PrintWriter(clientSocket.getOutputStream(), true);
) {
socketIsAlive=true;
new ConnectionChecker(clientSocket).start();
String input;
while (true) {
if ((input=stdIn.readLine())!=null)
socketOut.println(input);
if (!socketIsAlive) {
System.out.println("Got socket error");
break;
}
}
} catch (IOException e) {
try {
Thread.sleep(5000);
} catch (InterruptedException e1) {}
}
}
...
static public class ConnectionChecker extends Thread{
Socket socket;
public ConnectionChecker(Socket socket) {
this.socket=socket;
}
#Override
public void run() {
try {
if (socket.getInputStream().read()==-1)
socketIsAlive=false;
} catch (IOException e) {}
}
}
When I receive data using Socket.getInputStream() directly (without some kind of interface like Scanner), it doesn't block. But, when I try to use a Scanner (similar to how we receive Strings from System.in), it does. I was wondering the reason for this, and how the InputStream that a connected Socket supplies to you is different from the InputStream in in System.
The Client used for testing (used for both servers)
The code that hangs:
public class Server {
public static void main(String[] args) {
try {
ServerSocket ss = new ServerSocket(15180);
Socket socket = ss.accept();
Scanner scanner = new Scanner(socket.getInputStream());
//read data from client
while(true) {
String data = scanner.nextLine();
System.out.println("Received data!");
}
}catch(IOException e) {
e.printStackTrace();
}
}
}
The code that doesn't block:
public class Server {
public static void main(String[] args) {
try {
ServerSocket ss = new ServerSocket(15180);
Socket socket = ss.accept();
//read data from client
while(true) {
int data = socket.getInputStream().read();
System.out.println("Received data!");
}
}catch(IOException e) {
e.printStackTrace();
}
}
}
(I think you've already figured this out but ...)
The readLine() method returns the rest of the current line. That is, all unconsumed characters up to the next "end of line" sequence, or the "end of stream", which ever comes first. It will block, waiting until the current line (according to the above) is available.
So if your socket readLine() call blocks, it is waiting for the remote to either send an end-of-line marker (e.g. '\n'), or close its socket output stream (which will result in an "end-of-stream" at this end).
Q: Why does it "work" when you read from the console?
A: The console adds an "end-of-line" sequence to the stream whenever you hit ENTER. (Precisely what sequence is added is OS dependent, but the Scanner class will cope with all common varieties, and some unusual ones too.)
The lesson here is that you should only use Scanner.readLine() if the input stream is line oriented; i.e. if whatever wrote / generated the stream is including "end-of-line" markers.
Thank everyone to see my problem.
I'd like to explain my problem on Socket with java.
Using socket ,one for server to waiting for connection from client, the other for client to connect with server. THERE ARE TWO PROBLEM~~
(1)
+++After they all connect with each other, the two side can exchange messages to each other. I'have already finished the two Application code with server and client with each own main THREAD,but I can't let them communicate with each other. I use windows command to run this two file .class. I run server first ,and then I run client. They can't communicate with each other. I Want to know whether this is a problem about congestion.If I establish a another thread ,this problem could be solved??
(2) I attempt to run this two application on two eclipse,in other words each eclipse run one application. Why this problem can be solved??
(3)HERE is my code for client:
import java.util.*;
import java.io.*;
import java.net.*;
public class CC {
public static void main(String args[]){
Socket client=null;
DataInputStream in=null;
DataOutputStream out=null;
try{
client=new Socket("127.0.0.1",2060);
in=new DataInputStream(client.getInputStream());
out=new DataOutputStream(client.getOutputStream());
System.out.println("You are a client,you send message to server");
Scanner cin=new Scanner(System.in);
while(true){
String send=null,receive=null;
System.out.println("Please input Client message sending to server!");
send=cin.nextLine();
out.writeUTF(send);
receive=in.readUTF();
System.out.println("Message from Server is:"+receive);
Thread.sleep(500);
}
}
catch(Exception e){
System.out.println("break!"+e);
}
}
}
Here is my code for server
import java.util.*;
import java.io.*;
import java.net.*;
public class SS {
public static void main(String args[]){
ServerSocket socketServer=null;
DataInputStream in=null;
DataOutputStream out=null;
Socket server;
try{
socketServer=new ServerSocket(2060);
}
catch(Exception e1){
System.out.println("can't estblish socketServer "+e1);
}
try{
Scanner cin=new Scanner(System.in);
System.out.println("you are server ,please send message to client");
server=socketServer.accept();
in=new DataInputStream(server.getInputStream());
out=new DataOutputStream(server.getOutputStream());
while(true){
String send=null,receive=null;
receive=in.readUTF();
System.out.println("get message from client is "+receive);
System.out.println("send message from client");
send=cin.nextLine();
out.writeUTF(send);
}
}
catch(Exception e){
System.out.println("break! "+e);
}
}
}
The server and client code deadlocks.
In the client code you have written send=cin.nextLine();, which blocks until more input is available. In the server code you have written receive=in.readUTF(); which too blocks until input is available.
That is, immediately after a connection is established, both the server and the client expects the other to send something which results in a deadlock and both of them wait indefinitely.
You have to make sure that either the server or the client first sends some output before waiting to accept input.
thank you,I have solve this problem under my friends.Because I have run this application before,the port has been occupied.Then I run this application for the second time,this result these two application can not transfer message. These two Application is totally right.
I'm getting different results while trying to read from a socket while the other socket is closed.
I have two sockets A and B.
1)B sent some data to A --> A has read the data --> A closes --> When B tries to read some data from A, it is getting -1(or EOF).
2)B sent some data to A --> A closes even before reading the data --> Now B tries to read from A, an exception is thrown(java.net.SocketException "Software caused connection abort.")
please excuse me, if you can't understand my question. Please see the code
Server.java
import java.io.*;
import java.net.*;
class SocketCloser extends Thread
{
private Socket c;
public SocketCloser(Socket c) {
this.c = c;
}
public void run() {
try{
this.c.close();
} catch (Exception e) {}
}
}
public class Server
{
public static void main(String argv[]) throws Exception {
ServerSocket listen = new ServerSocket(6789);
Socket socket = listen.accept();
SocketCloser sc = new SocketCloser(socket);
InputStream is = socket.getInputStream();
// uncomment below line to get "Software caused connection abort" on client
//sc.start();
try {
Thread.sleep(1000);
int i = is.read();
System.out.println("read returned: " + i);
socket.close();
} catch (Exception e) {
System.out.println(e.toString() + " thrown");
}
}
}
Client.java
import java.io.*;
import java.net.*;
public class Client
{
public static void main(String argv[])
{
Socket cSocket;
try {
cSocket = new Socket("localhost", 6789);
InputStream is = cSocket.getInputStream();
OutputStream os = cSocket.getOutputStream();
Thread.sleep(1000);
os.write(200);
Thread.sleep(1000);
int i = is.read();
System.out.println("read returned: " + i);
cSocket.close();
} catch (Exception e) {
System.out.println(e.toString() + " thrown");
}
}
}
Can someone please help me figure out why there is an exception in one case and -1 in another. Interestingly on linux both the cases resulted in -1.
1) Because B established a connection, A goes to CLOSE_WAIT. It will be in that state until B closes the connection. There is nothing to read, so the read() call on B's InputStream returns -1.
2) A is blocked in the accept call. The other thread is trying to close the socket, but it can't because accept is blocking it. When B connects, accept unblocks and the socket closes outright. When B tries to read, the socket is not there anymore so you get the exception.
I'm simplifying a bit, but that's the gist of it.
1)B sent some data to A --> A has read the data --> A closes --> When B tries to read some data from A, it is getting -1(or EOF).
I agree. What did you expect? This is the expected behaviour.
2)B sent some data to A --> A closes even before reading the data --> Now B tries to read from A, an exception is thrown(java.net.SocketException "Software caused connection abort.")
I agree. This is one of the expected behaviours in this incorrect situation. What did you expect?
please excuse me, if you can't understand my question.
There is no question here to understand. You haven't asked a question. You close a socket without sending any data and the peer gets EOS without receiving any data. You close a socket while the peer is sending and the peer gets an exception. System is working as designed.
I have a class implementing serversocket class and there is another class implementing the client 1. Socket class.
So what I am trying to do is that. After getting the streams I want client to send a number to server and server will in turn respond to client whether it's prime or not. Which is display in an awt.Label.
But I am not able to receive any response.
Here is the code for client's constructor:
public ClientIsPrime()
{
setLayout(new GridLayout(2,2));
add(new Label("Enter a number: "));
add(numEntry=new TextField(10));
add(checkPrime=new Button("Check if number is Prime"));
add(result=new Label("Result is shown here"));
try
{
Socket client = new Socket(InetAddress.getLocalHost(), 5959);
in=client.getInputStream();
out=client.getOutputStream();
}catch(UnknownHostException e)
{
result.setText("Local Host cannot be resolved");
}catch(IOException e)
{
result.setText("IOException occured");
}
checkPrime.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
try
{
int num;
num=Integer.parseInt(numEntry.getText());
out.write(num);
out.flush();
int c;
result.setText("");
String s="";
while((c=in.read())!=-1)
s+=((char)c);
result.setText(s);
}catch(IOException e)
{
result.setText("IOException occured");
}catch(NumberFormatException e)
{
result.setText("Please enter a valid number.");
}
}
});
}
Code for Server:
public static void main(String args[])throws IOException
{
server=new ServerSocket(5959);
socket=server.accept();
System.out.println("connected");
InputStream in=socket.getInputStream();
OutputStream out=socket.getOutputStream();
int c; String numStr="";
while((c=in.read())!=-1)
numStr+=((char)c);
int num=Integer.parseInt(numStr);
if(num==3)
out.write("Number is Prime".getBytes());
else
out.write("Number is not Prime".getBytes());
out.flush();
in.close();
out.close();
}
It isn't a real app. I am learning.
A few problems.
First your server implementation will never exit the while loop. The API for InputStream.read() states that it will block until data is received or the stream is closed. The stream is never closed so the reading will block forever after reading the initial data.
To solve this problem you must decide what your protocol is. See below.
The other problem is that you are writing from the client as a parsed int of text. So say 13 (as an int). But you are then reading it as if it were a sequence of characters. 13 on the wire will be read as some control character. You need to be consistent with how you write data and read data.
My suggestion would be to have a basic protocol. Use DataOutputStream on the writing side and DataInputStream on the reading side and then match the read/write calls on both sides to ensure you are consistent.
If you want to sent integers across the wire it is infinitely easier to layer a DataOutputStream/DataInputStream on top of the raw socket streams and just do writeInt() and readInt()