EDIT: A poorly researched question, written when I was in a rush-it has nothing to do with socket.accept()-see below for accepted answer.Please no more downvoting.
I'm new to socket programming and in my toy 'Server' class I'm not getting any lines from the peer:
public class Server {
private ServerSocket myServerSocket;
String messageFromClient=null;
private void startServer(){
try{
myServerSocket=new ServerSocket(2000);
int portUsed= myServerSocket.getLocalPort();
System.out.println(portUsed);
Socket mySocket=myServerSocket.accept();
System.out.println("accepted");
InputStreamReader streamFromClient = new InputStreamReader(mySocket.getInputStream());
BufferedReader streamReader= new BufferedReader(streamFromClient);
messageFromClient=streamReader.readLine();
System.out.println("current message:"+messageFromClient);
if(messageFromClient!=null){
PrintStream ps = new PrintStream(mySocket.getOutputStream());
ps.print("Thank you client, I gratefully received from your message-hi from server!");
}
}
catch(Exception e){
e.printStackTrace();
}
}
for completeness, here is the client class:
public class Client {
#SuppressWarnings("resource")
private void startClient(){
try{
Socket socket = new Socket("localhost",2000);
PrintStream ps = new PrintStream(socket.getOutputStream());
ps.print("hi from client");
InputStreamReader inputStreamReader=new InputStreamReader(socket.getInputStream());
BufferedReader reader=new BufferedReader(inputStreamReader);
System.out.println("From Server:"+reader.readLine());
}
catch(Exception e){
e.printStackTrace();
}
}
They both have main methods. Any help would be very much appreciated thanks you!
You need to use println instead of all prints. As an explanation, while your server is waiting for an end of line character your client never sends. And it is same for when your server sends a message.
Related
This is what I want to achieve:
There are client and server sockets. The client socket will send a message to the server (for instance "add:2:3" to add 2 and 3, etc). The server should response with an answer. When the answer arrives, the client can send additional message (like "subtract:5:8" to subtract 5 from 8), etc... Thus the client will send a message, then it will get a response, then it will send the next message and get a response, etc. Am sending the message from the command line.
This is what I have now but it is not working:
// Server code
public class MT extends Thread{
private Socket sock;
private BufferedReader rd;
private OutputStreamWriter wr;
private Client client;
public MT(Socket sock) throws IOException {
this.sock= sock;
rd = new BufferedReader(new InputStreamReader(sock.getInputStream()));
wr = new OutputStreamWriter(sock.getOutputStream());
wr.write("You are welcome" + "\n");
wr.flush();
}
public void run(){
try{
while(true){
String command = reader.readLine();
// Will process data here and then send results to client
// At the moment i just want to send the message back to client
wr.write(command + "\n"); // send results to client
}
}
}
}catch(IOException ex){
System.err.println("Problem reading data from client");
}
}
}
public class MyServio {
public static void main(String[] args) {
try(ServerSocket server = new ServerSocket()){
server.bind(new InetSocketAddress("0.0.0.0", 4444));
System.out.println("Listening...");
try{
while(true){
Socket con = server.accept();
Thread a = new MT(con);
a.start();
}
}catch(IOException ex){
System.err.println("Problem...");
}
}catch(IOException ex){
System.err.println("Server Issues");
}
}
}
// Client
For the client I decided to use two threads to read and write to the server
public class MyRead extends Thread{
private BufferedReader r;
public ReadFromServer(BufferedReader r){
this.r = r;
}
#Override
public void run() {
StringBuilder m = new StringBuilder();
try {
while(true){
message.append(r.readLine());
System.out.println(m);
}
} catch (IOException e) {
System.out.println("Problem in MyRead");
e.printStackTrace();
}
}
}
public class MyWrite extends Thread{
private OutputStreamWriter w;
Scanner sc;
public WriteToServer(OutputStreamWriter w){
this.w = w;
sc = new Scanner(System.in);
}
#Override
public void run() {
try {
while(true){
System.out.print("Type message: ");
String msg = sc.nextLine();
w.write(msg + "\n");
w.flush();
}
} catch (IOException e) {
System.out.println("Problem in MyWrite");
e.printStackTrace();
}
}
}
public class CSock {
private OutputStreamWriter w;
private BufferedReader r;
public ClientSocket() {}
public void do(){
InetAddress ad = null;
try {
ad = InetAddress.getByName("127.0.0.1");
} catch (UnknownHostException e) {
System.err.println("Error InetAddress");
}
try (Socket s = new Socket(addr, PORT)) {
System.out.println("Server connecting...");
StringBuilder message = new StringBuilder();
r = new BufferedReader(new InputStreamReader(s.getInputStream()));
w = new OutputStreamWriter(s.getOutputStream());
message.append(r.readLine()); // reads the welcome message from server
System.out.println(message);
// I start the read and write threads so that the client can read and write message to the server
ReadFromServer rd = new ReadFromServer(r);
WriteToServer wt = new WriteToServer(w);
rd.start();
wt.start();
} catch (IOException ex) {
System.err.println("problem connecting to server");
}
}
}
public class Main {
public static void main(String[] args){
ClientSocket clientSocket = new ClientSocket();
clientSocket.do();
}
}
I start the server first, and then I start the client, but the client gives an exception:
Problem in MyRead
java.net.SocketException: socket closed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.net.SocketInputStream.read(SocketInputStream.java:170)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:161)
at java.io.BufferedReader.readLine(BufferedReader.java:324)
at java.io.BufferedReader.readLine(BufferedReader.java:389)
at model.ReadFromServer.run(ReadFromServer.java:31)
The last line in the exception indicates that message.append(reader.readLine()); in the code is the problem. I don't close sockets or input stream or output stream anywhere in my code, yet I get this exception.
Also get similar socket closed exception in the MyWrite class in the run() method in the following line writer.flush();
In the client on this line
try (Socket s = new Socket(addr, PORT)) {
You're telling the jvm that it should close the socket after executing the try statement.
This line is creating a reader from the output stream of the socket.
r = new BufferedReader(new InputStreamReader(s.getInputStream()));
And this is creating a functionality that read from server.
ReadFromServer rd = new ReadFromServer(r);
ReadFromServer is a thread, and it's free to execute after the try-catch statement has finished. So when it execute reader.readLine() the socket is closed.
You closed the socket and then continued to use it. The try-with-resource statement closed the socket; the two threads you started continued to use it.
I am a student and learning Network Programming and have a some problem.
This is my client:
public class Test2Client_Tranfer_An_Obj {
Socket socket = null;
ObjectOutputStream out;
ObjectInputStream in;
public Test2Client_Tranfer_An_Obj() {
try {
socket = new Socket("localhost", 12345);
out = new ObjectOutputStream(socket.getOutputStream());
in = new ObjectInputStream(socket.getInputStream());
System.out.println("Ready");
System.out.println("" + in.readUTF());
System.out.println("" + in.readUTF());
System.out.println("Recived");
out.writeUTF("hihi");
System.out.println("Sended");
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
System.out.println("Client");
Test2Client_Tranfer_An_Obj test = new Test2Client_Tranfer_An_Obj();
}
}
This my Server:
public class Test2Server_Tranfer_An_Obj {
ServerSocket serverSocket;
ObjectOutputStream out;
ObjectInputStream in;
public Test2Server_Tranfer_An_Obj() {
try {
serverSocket = new ServerSocket(12345);
Socket socket = serverSocket.accept();
out = new ObjectOutputStream(socket.getOutputStream());
in = new ObjectInputStream(socket.getInputStream());
System.out.println("Ready!");
out.writeUTF("huhu");
out.writeUTF("hoho");
System.out.println("Sended");
String s = in.readUTF();
System.out.println("" + s);
System.out.println("Recived");
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
System.out.println("Server");
Test2Server_Tranfer_An_Obj demo = new Test2Server_Tranfer_An_Obj();
}
}
But, when i run my program, this result:
Server Console
Server
Ready!
Sended
Client Console
Client Ready
Anybody can tell me why and what i can do?
Thank for reading!
Hope recive you answer
Object Stream is overkill in this case. You are not actually using writeObject/readObject and using DataInputStream and DataOutputStream would do what you want.
In this particular case, an Object Stream is buffered, which means that small writes are buffered until you either flush() or close() the stream to improve performance. As you don't do either, the writeUTF only writes to memory, not the Socket.
c.f. Data Streams are not buffered by default.
In your server after write to the outputstream. you have to add out.flush() to write to socket
Hello programmers on the internet. I am currently stepping through an operating systems book and there are some exercises that involve the following pieces of code.
This is the server code
import java.net.*;
import java.io.*;
public class DateServer{
public static void main(String[] args) {
try {
ServerSocket sock = new ServerSocket(6013);
// now listen for connections
while (true) {
Socket client = sock.accept();
PrintWriter pout = new
PrintWriter(client.getOutputStream(), true);
// write the Date to the socket
pout.println(new java.util.Date().toString());
// close the socket and resume
// listening for connections
client.close();
}
}
catch (IOException ioe) {
System.err.println(ioe);
}
}
}
This is the client code
import java.net.*;
import java.io.*;
public class DateClient{
public static void main(String[] args) {
try {
//make connection to server socket
Socket sock = new Socket("127.0.0.1",6013);
InputStream in = sock.getInputStream();
BufferedReader bin = new
BufferedReader(new InputStreamReader(in));
// read the date from the socket
String line;
while ( (line = bin.readLine()) != null)
System.out.println(line);
// close the socket connection
sock.close();
}
catch (IOException ioe) {
System.err.println(ioe);
}
}
}
So to my understanding the server is creating a socket and writing a date value to it. The client is then coming a long and connecting to the server and writing out the value in that socket. Am I interpreting this code correctly? This is my first experience with sockets.
Now for my actual question. I want to have the client connect to the server (and print out a message saying you are connected) and then be able to send a value over to the server so that the server can process it. How would I go about doing this? I have tried tinkering with DataOutputStream and DataInputStream but I have never used either before. Any help would be GREATLY appreciated.
You are correct. You have the server writing to the socket and the client reading from the socket. You want to reverse that.
Server Should look like:
ServerSocket sock = new ServerSocket(6013);
// now listen for connections
while (true)
{
Socket client = sock.accept();
InputStream in = client.getInputStream();
BufferedReader bin = new BufferedReader(new InputStreamReader(in));
// read the date from the client socket
String line;
while ((line = bin.readLine()) != null)
System.out.println(line);
// close the socket connection
client.close();
}
The client should look like:
try
{
// make connection to server socket
Socket sock = new Socket("127.0.0.1", 6013);
PrintWriter out = new PrintWriter(sock.getOutputStream(), true);
// send a date to the server
out.println("1985");
sock.close();
}
catch (IOException ioe)
{
System.err.println(ioe);
}
I'm trying to make a little chat system. I have a console and a client. Right now only the client need to send messages to the console. I can connect successfully to the server, and i can send one message from client to console. The trouble begins after sending the first message. When the first message i can't send any other messages.
I don't know if it's the console that won't read the message or the client that won't send the message. In this case how could i troubleshoot this?
public class ClientMainClass {
private static Socket socket;
public static void main(String args[]) {
try {
String host = "localhost";
int port = 25000;
InetAddress address = InetAddress.getByName(host);
socket = new Socket(address, port);
Scanner scanner = new Scanner(System.in);
System.out.println("Skriv dit username:");
String name = scanner.nextLine();
System.out.println("Du er logget ind som: " + name);
String input;
do{
input = scanner.nextLine();
if (input.equalsIgnoreCase("exit")) {
System.out.println("Du forlod serveren");
socket.close();
continue;
}else {
/*OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);*/
PrintWriter printWriter = new PrintWriter(socket.getOutputStream(),true);
Date date = new Date();
String time = date.getDate()+"/"+date.getMonth()+":"+date.getHours()+":"+date.getMinutes();
//Send the message to the server
String message = time+ " - " + name + ": "+input;
printWriter.println(message);
System.out.println(message);
continue;
}
}while (!(input.equals("exit")));
} catch (Exception exception) {
exception.printStackTrace();
} finally {
//Closing the socket
try {
socket.close();
} catch(Exception e) {
e.printStackTrace();
}
}
}
}
My server:
public class Main{
private static Socket socket;
public static void main(String[] args) {
try {
int port = 25000;
ServerSocket serverSocket = new ServerSocket(port);
System.out.println("Server Started and listening to the port 25000");
while(true) {
//Reading the message from the client
socket = serverSocket.accept();
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
System.out.println(br.readLine());
}
}
catch (Exception e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch(Exception e){}
}
}
}
To be clear. I can connect to the server. I can send one message from client to console, but no more than one message.
You never read a second line. Your Server accepts a connection, reads one line from that connection and then waits for a new connection, discarding everything that might arrive at the first connection.
Your client however sends all input using the first (and only) connection, which is absolutely correct.
This specific problem can be solved like this:
while(true) {
//Reading the message from the client
socket = serverSocket.accept();
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
while(true){
System.out.println(br.readLine());
}
}
This will cause your program to print everything arriving on that first connection, but it will never accept a second connection.
In order to handle multiple clients, you need a Thread to deal with each one.
I'm having some trouble simulating a connection to my Server Socket, accept seems to continue blocking as it doesn't "see" the connection.
Here's some simplified code
#Test
public void testPDMServerThread() {
try {
ServerSocket serverSocket = new ServerSocket(0);
int port = serverSocket.getPort();
Socket clientSocket = new Socket("localhost", port);
PrintWriter clientRequest = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader serverResponse = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
serverThread = new ProducerMonitorServerThread(serverSocket.accept());
clientRequest.write("Hi!");
serverThread.start();
System.out.println("Server says: " + serverResponse.readLine());
assertEquals("RUNNABLE", serverThread.getState().toString());
} catch (IOException e) {
}
}
And here's the thread where the server should respond
public class ProducerMonitorServerThread extends Thread {
private Socket socket;
public ProducerMonitorServerThread(Socket socket) {
super("PDM");
this.socket = socket;
}
#Override
public void run() {
try {
PrintWriter serverResponse = new PrintWriter(socket.getOutputStream(), true);
BufferedReader clientRequest = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
String serverInput, clientOutput;
while((serverInput = clientRequest.readLine()) != null) {
clientOutput = "Bye!";
System.out.println("Client says: " +serverInput);
serverResponse.write(clientOutput);
}
serverResponse.close();
clientRequest.close();
socket.close();
} catch (IOException e) {
}
}
}
It never seems to get past this line which is why I think accept is not seeing the connection
serverThread = new ProducerMonitorServerThread(testServer.accept());
I'm sure there's something fundamental that I'm just not seeing.
First of all, you should not ignore exceptions like you're doing.
The problem is not with accept. The problem is that the server uses readLine(), and the client never sends any EOL character, and never closes the socket. So the server is blocked waiting for an EOL to appear in the reader. The same is true for the client: it uses readLine() and the server never sends any EOL.
Use a debugger. It will help you find the cause of such problems.