I have an XBee-PRO S1 on Arduino Uno R3 which acts like a transmitter to send data to another XBee which is acting like a receiver to turn on the LEDs connected to it. Here is what I'm doing:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import gnu.io.CommPortIdentifier;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import gnu.io.UnsupportedCommOperationException;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.TooManyListenersException;
public class NewClass implements SerialPortEventListener {
SerialPort serialPort;
OutputStream out;
private static final String PORT_NAME = "COM10"; //(XBee Transmitter)
private BufferedReader input;
private static final int TIME_OUT = 2000;
private static final int DATA_RATE = 9600;
// End of input chars
//private static final byte EOIC = 3;
public void initialize() {
CommPortIdentifier portId = null;
Enumeration portEnum = CommPortIdentifier.getPortIdentifiers();
//First, find an instance of serial port as set in PORT_NAME.
while (portEnum.hasMoreElements()) {
CommPortIdentifier currPortId = (CommPortIdentifier) portEnum.nextElement();
if (currPortId.getName().equals(PORT_NAME)) {
portId = currPortId;
}
}
if (portId == null) {
System.out.println("Could not find COM port.");
return;
}
try {
serialPort = (SerialPort) portId.open(this.getClass().getName(), TIME_OUT);
serialPort.setSerialPortParams(DATA_RATE, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
// Open the input stream
input = new BufferedReader(new InputStreamReader(serialPort.getInputStream()));
serialPort.addEventListener(this);
serialPort.notifyOnDataAvailable(true);
serialPort.setEndOfInputChar((byte) 3);
}
catch (PortInUseException | UnsupportedCommOperationException | IOException | TooManyListenersException e) {
System.err.println(e.toString());
}
}
public synchronized void close() {
if (serialPort != null) {
serialPort.removeEventListener();
serialPort.close();
}
}
#Override
public synchronized void serialEvent(SerialPortEvent oEvent) {
if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
try {
char inputLine;
//dat = new ArrayList<Character>();
if (input.ready()) {
inputLine = (char) input.read();
Thread.sleep(1500);
sendChar();
}
}
catch (Exception e) {
System.err.println(e.toString());
System.out.println("Error reading");
}
}
// Ignore all the other eventTypes, but you should consider the other ones.
}
public synchronized void sendChar() {
try {
Thread.sleep(1500);
out = serialPort.getOutputStream();
System.out.println("out is not null");
for (int i = 0; i <= 900; i++) {
Thread.sleep(1500);
out.write((char) 'A');
out.flush();
System.out.println(i+") written-> A"); //For debugging
}
}
catch (InterruptedException | IOException e) {
}
}
public synchronized void cRead(char data) {
if (data != ' ') {
System.out.print(data);
//getTimestamp();
}
}
public static void main(String[] args) throws Exception {
NewClass main = new NewClass();
main.initialize();
Thread t = new Thread() {
#Override
public void run() {
//The following line will keep this application alive for 12 hours,
//waiting for events to occur and responding to them (printing
//incoming messages to console).
try {
Thread.sleep(43200000);
}
catch (InterruptedException ie) {
}
}
};
t.start();
System.out.println("Started");
}
}
One problem with this code is that, when I get some incoming signal at the COM port then only the sendChar() is called which is due to the condition if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE). Also the data is not being sent. I don't know what other event types are there because of lack of proper documentation.
What I want is to send data to Arduino without receiving anything. What am I doing wrong or missing?
Related
client connection works (I use telnet), but nothing happens when I write a message with any client - even the condition with empty char (for disconnection).
I don't understand why. I get capacity and port with args[], and I start the server.
I already tested a simpler version with just a server which can handle one by one client, and it works.
public class EchoClient extends Thread {
EchoServerForPool serv;
BufferedReader inchan;
DataOutputStream outchan;
Socket socket;
int port;
public EchoClient(EchoServerForPool serv) {
// TODO Auto-generated constructor stub
this.serv = serv;
}
#Override
public void run() {
// TODO Auto-generated method stub
Socket s;
while (true) {
synchronized (this.serv) {
if (this.serv.stillWaiting() == 0) {
try {
this.serv.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
s = this.serv.removeFirstSocket();
serv.newConnect();
}
try {
inchan = new BufferedReader(new InputStreamReader(s.getInputStream()));
outchan = new DataOutputStream(s.getOutputStream());
String message = inchan.readLine();
if (message.equals("")) {
System.out.println("fin de connection");
break;
}
outchan.writeChars(message + "\n");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
s.close();
synchronized (serv) {
serv.clientLeft();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class EchoServerForPool extends Thread {
ArrayList<EchoClient> clients;
ArrayList<Socket> sockets;
Socket client;
int nbLocalhost = 0;
int capacity, port, nbConnectedClient, nbWaitingSocket;
public EchoServerForPool(int capacity, int port) {
// TODO Auto-generated constructor stub
this.capacity = capacity;
this.port = port;
clients = new ArrayList<EchoClient>(capacity);
sockets = new ArrayList<Socket>();
for (int i = 0; i < clients.size(); i++) {
EchoClient ec_i = new EchoClient(this);
clients.add(ec_i);
ec_i.start();
}
}
public Socket removeFirstSocket() {
Socket res = sockets.get(0);
sockets.remove(0);
return res;
}
public void newConnect() {
nbConnectedClient++;
nbWaitingSocket--;
}
public int stillWaiting() {
return nbWaitingSocket;
}
public void clientLeft() {
nbConnectedClient--;
}
#Override
public void run() {
// TODO Auto-generated method stub
try {
ServerSocket serv = new ServerSocket(this.port);
while (true) {
this.client = serv.accept();
synchronized (this) {
nbLocalhost++;
System.out.println(client.getInetAddress().getHostName() + "-" + nbLocalhost + " connected");
sockets.add(client);
nbWaitingSocket++;
notify();
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class EchoPoolThread {
public static void main(String[] args) {
int port = Integer.parseInt(args[0]);
int capacity = Integer.parseInt(args[1]);
EchoClient.EchoServerForPool serveur = new EchoClient.EchoServerForPool(capacity, port);
System.out.println("start server");
serveur.start();
}
}
EDIT : the problem was I iterate with clients.size() which is 0 instead of capacity, for fill my clients list....
I've refactored your code a little bit to have a working solution. You can work from there to create a pool, right now the number of clients isn't limited.
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* #author Gianlu
*/
public class Main {
public static void main(String[] args) {
int port = Integer.parseInt(args[0]);
int capacity = Integer.parseInt(args[1]);
EchoServerForPool serveur = new EchoServerForPool(capacity, port);
System.out.println("start server");
serveur.start();
}
public static class EchoServerForPool extends Thread {
private final int port;
private final ExecutorService executor;
private final ArrayList<EchoClient> clients;
private int nbLocalhost = 0;
public EchoServerForPool(int capacity, int port) {
this.port = port;
clients = new ArrayList<>();
executor = Executors.newFixedThreadPool(capacity);
}
#Override
public void run() {
try {
ServerSocket serv = new ServerSocket(this.port);
while (true) {
Socket socket = serv.accept();
EchoClient client = new EchoClient(this, socket);
executor.submit(client);
clients.add(client);
nbLocalhost++;
System.out.println(socket.getInetAddress().getHostName() + "-" + nbLocalhost + " connected");
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void terminated(EchoClient client) {
clients.remove(client);
}
}
public static class EchoClient implements Runnable {
private final EchoServerForPool pool;
private final Socket socket;
private final BufferedReader inchan;
private final DataOutputStream outchan;
public EchoClient(EchoServerForPool pool, Socket socket) throws IOException {
this.pool = pool;
this.socket = socket;
this.inchan = new BufferedReader(new InputStreamReader(socket.getInputStream()));
this.outchan = new DataOutputStream(socket.getOutputStream());
}
#Override
public void run() {
try {
while (true) {
String message = inchan.readLine();
if (message.equals("")) {
System.out.println("fin de connection");
break;
}
outchan.writeChars(message + "\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
pool.terminated(this);
}
}
}
Using eclipse and java how to read the data from the pcb board with a serial cable, because the data of the pcb board arrive via cable in binary format. How to save the data that will be displayed in the compiler?
Someone help me please.
Below is the code I am writing to do this, but it does not detect any port when I plug in the serial cable
import gnu.io.*;
import java.awt.Color;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.TooManyListenersException;
public class SimpleRead implements Runnable, SerialPortEventListener {
static CommPortIdentifier portId;
static Enumeration portList;
InputStream inputStream;
SerialPort serialPort;
Thread readThread;
public static void main(String[] args) {
boolean portFound = false;
String defaultPort ="COM 1" ;
if (args.length > 0) {
defaultPort = args[0];
}
portList = CommPortIdentifier.getPortIdentifiers();
while (portList.hasMoreElements()) {
portId = (CommPortIdentifier) portList.nextElement();
if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
if (portId.getName().equals(defaultPort)) {
System.out.println("Found port: "+defaultPort);
portFound = true;
SimpleRead reader = new SimpleRead();
}
}
}
if (!portFound) {
System.out.println("port " + defaultPort + " not found.");
}
}
public SimpleRead() {
try {
serialPort = (SerialPort) portId.open("SimpleReadApp", 2000);
} catch (PortInUseException e) {}
try {
inputStream = serialPort.getInputStream();
} catch (IOException e) {}
try {
serialPort.addEventListener(this);
} catch (TooManyListenersException e) {}
serialPort.notifyOnDataAvailable(true);
try {
serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
} catch (UnsupportedCommOperationException e) {}
readThread = new Thread(this);
readThread.start();
}
public void run() {
try {
Thread.sleep(20000);
} catch (InterruptedException e) {}
}
public void serialEvent(SerialPortEvent event) {
switch (event.getEventType()) {
case SerialPortEvent.BI:
case SerialPortEvent.OE:
case SerialPortEvent.FE:
case SerialPortEvent.PE:
case SerialPortEvent.CD:
case SerialPortEvent.CTS:
case SerialPortEvent.DSR:
case SerialPortEvent.RI:
case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
break;
case SerialPortEvent.DATA_AVAILABLE:
byte[] readBuffer = new byte[20];
try {
while (inputStream.available() > 0)
{
int numBytes = inputStream.read(readBuffer);
System.out.print("The Read Bytes from SerialPort are");
System.out.write(readBuffer);
System.out.println();
}
System.out.print(new String(readBuffer));
} catch (IOException e) {}
break;
}
}
}
Log Result:
port COM 1 not found.
The port names don't have spaces in them. Try changing:
String defaultPort ="COM 1" ;
to:
String defaultPort ="COM1" ;
I have Honeywell USB barcode scanner. I want to read input of barcode scanner by using Java code.
I got solution by below code but i dont want to use any gui.
import java.awt.AWTEvent;
import java.awt.FlowLayout;
import java.awt.Toolkit;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.WindowConstants;
public class BarcodeScaner extends JFrame {
private static String strBarcode = "";
private static JTextField jtBarcode = new JTextField(25);
public BarcodeScaner() {
getContentPane().setLayout(new FlowLayout());
getContentPane().add(new JLabel("Capture barcode "));
getContentPane().add(jtBarcode);
}
public static void main(String[] args) {
BarcodeScaner br = new BarcodeScaner();
readBarCode();
br.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
br.setVisible(true);
br.pack();
}
private static void readBarCode() {
// start of listening for barcode events
Toolkit.getDefaultToolkit().addAWTEventListener(new BarcodeAwareAWTEventListener(new BarcodeCapturedListener() {
#Override
public void barcodeCaptured(String barcode) {
strBarcode = barcode;
System.out.println("====="+barcode);
jtBarcode.setText(strBarcode);
}
}), AWTEvent.KEY_EVENT_MASK);
// end of listening for barcode events
}
}
In above code i have to focus on textbox then only i get scanned value.
I have search in stackoverflow but i didnt get any specific solution.
I also try this below code but still serialEvent is not execute.
package scanhandler;
import java.awt.AWTException;
import java.awt.Robot;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.util.Enumeration;
import java.util.Properties;
import java.util.TooManyListenersException;
import javax.comm.CommPortIdentifier;
import javax.comm.PortInUseException;
import javax.comm.SerialPort;
import javax.comm.SerialPortEvent;
import javax.comm.SerialPortEventListener;
import javax.comm.UnsupportedCommOperationException;
public class ScanHandler implements Runnable, SerialPortEventListener {
private static CommPortIdentifier myCommPortIdentifier;
private static Enumeration portList;
private static String TimeStamp;
private static String driverClass;
private static String connectionString;
private static String comPort;
private Connection myConnection;
private InputStream myInputStream;
private Robot myRobot;
private SerialPort mySerialPort;
private Thread myThread;
public ScanHandler() {
// open serial port
try {
TimeStamp = new java.util.Date().toString();
mySerialPort = (SerialPort) myCommPortIdentifier.open("ComControl", 2000);
//System.out.println(TimeStamp + ": " + myCommPortIdentifier.getName() + " opened for scanner input");
} catch (PortInUseException e) {
e.printStackTrace();
}
// get serial input stream
try {
myInputStream = mySerialPort.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
// add an event listener on the port
try {
mySerialPort.addEventListener(this);
} catch (TooManyListenersException e) {
e.printStackTrace();
}
mySerialPort.notifyOnDataAvailable(true);
// set up the serial port properties
try {
mySerialPort.setSerialPortParams(9600,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
mySerialPort.setDTR(false);
mySerialPort.setRTS(false);
} catch (UnsupportedCommOperationException e) {
e.printStackTrace();
}
// make a robot to pass keyboard data
try {
myRobot = new Robot();
} catch (AWTException e) {
e.printStackTrace();
}
// create the thread
myThread = new Thread(this);
myThread.start();
}
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {}
}
// on scan
public void serialEvent(SerialPortEvent event) {
if (event.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
StringBuilder myStringBuilder = new StringBuilder();
int c;
try {
// append the scanned data onto a string builder
while ((c = myInputStream.read()) != 10){
if (c != 13) myStringBuilder.append((char) c);
}
// send to keyboard buffer if it the barcode doesn't start with '5'
if (myStringBuilder.charAt(0) != '5') {
for (int i = 0; i < myStringBuilder.length(); i++) {
myRobot.keyPress((int) myStringBuilder.charAt(i));
myRobot.keyRelease((int) myStringBuilder.charAt(i));
}
// here's the scanned barcode as a variable!
} else {
TimeStamp = new java.util.Date().toString();
System.out.println(TimeStamp + ": scanned input received:" + myStringBuilder.toString());
}
// close the input stream
myInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
// read ScanHandler properties
Properties myProperties = new Properties();
try {
myProperties.load(new FileInputStream("config.properties"));
comPort = myProperties.getProperty("ScanHandler.comPort");
} catch (IOException e) {
e.printStackTrace();
}
try {
// get our pre-defined COM port
myCommPortIdentifier = CommPortIdentifier.getPortIdentifier(comPort);
ScanHandler reader = new ScanHandler();
} catch (Exception e) {
TimeStamp = new java.util.Date().toString();
System.out.println(TimeStamp + ": " + comPort + " " + myCommPortIdentifier);
System.out.println(TimeStamp + ": msg1 - " + e);
}
};
}
Please set the scanner to USB Serial mode by using the setting barcode stated in the user's guide.
Then install the serial port device driver of the OS of the machine to which the scanner is connected.
Then you can open the serial port and send commands to the scanner and receive barcode data.
I am try to receive data from my Arduino using an InputStream but for some reason I get this as the output.
ààà à àà ààà a ààà à àà ààààà àààààà à àà ààà à ààà à àà ààààà àààààà à àà ààà à
This is my code for receiving data:
package midistep;
import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import java.io.BufferedReader;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
public class TwoWaySerialComm
{
public OutputStream out1;
public TwoWaySerialComm()
{
super();
}
void connect ( String portName ) throws Exception
{
CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
if ( portIdentifier.isCurrentlyOwned() )
{
System.out.println("Error: Port is currently in use");
}
else
{
CommPort commPort = portIdentifier.open(this.getClass().getName(),2000);
if ( commPort instanceof SerialPort )
{
SerialPort serialPort = (SerialPort) commPort;
serialPort.setSerialPortParams(57600,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
InputStream in = serialPort.getInputStream();
OutputStream out = serialPort.getOutputStream();
out1=out;
(new Thread(new SerialReader(in))).start();
(new Thread(new SerialWriter(out))).start();
}
else
{
System.out.println("Error: Only serial ports are handled by this example.");
}
}
}
/** */
public static class SerialReader implements Runnable
{
InputStream in;
public SerialReader ( InputStream in )
{
this.in = in;
}
public void run ()
{
byte[] buffer = new byte[1024];
int len = -1;
try
{
while ( ( len = this.in.read(buffer)) > -1 )
{
System.out.print(new String(buffer,0,len));
}
}
catch ( IOException e )
{
e.printStackTrace();
}
}
}
/** */
public static class SerialWriter implements Runnable
{
public OutputStream out;
public SerialWriter ( OutputStream out )
{
this.out = out;
}
public void run ()
{
try
{
int c = 0;
while ( ( c = System.in.read()) > -1 )
{
this.out.write(c);
}
}
catch ( IOException e )
{
e.printStackTrace();
}
}
}
public void writetoport(int Steps) {
try {
out1.write(Steps);
out1.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main ( String[] args )
{
try
{
(new TwoWaySerialComm()).connect("COM3");
}
catch ( Exception e )
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
And my Arduino code:
int received = 0;
void setup() {
Serial.begin(9600);
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
delay(1000);
Serial.println("Hello world");
if (Serial.available() > 0) {
received = Serial.read();
if (received > 1000) {
int speed = received;
String tempstring = String(speed);
tempstring.substring(1);
speed = tempstring.toInt();
Serial.println("gotit" + speed);
}
else if (received = 1) {
Serial.print("I received something >");
Serial.print(received);
Serial.println("<");
digitalWrite(LED_BUILTIN, HIGH);
delay(1000);
digitalWrite(LED_BUILTIN, LOW);
}
}
}
Hopefully this is a simple problem. Thank you
You have set the wrong baud rate. You Java code has
serialPort.setSerialPortParams(57600,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
but in your Arduino sketch you have
Serial.begin(9600);
The baud rates must be identical else you'll get transmission errors.
I have a problem with readLine() in Java. I have a server and a client. From client I want to send a message to the server. The problem is that first, the client has to insert a text into a JTextField and when presses send then server to read the input from client, but server doesn't wait the input from client but instead reads null. But I read that readLine() is blocked until it has something to read, why it's not happening in this case?
Here I connect to the server and create the JFrame
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class StartingPoint {
private static PrintWriter out;
private static BufferedReader in;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
try {
connectToServer();
createAndShowGui();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
public static void createAndShowGui() throws IOException {
View frame = new View(out, in);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void connectToServer() throws IOException {
String serverAddress = "127.0.0.1";
int PORT = 8100;
Socket clientSocket = null;
out = null;
in = null;
try {
clientSocket = new Socket(serverAddress, PORT);
out = new PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(
clientSocket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Could not connect to the server \n" + e);
System.exit(1);
} finally {
if (out != null)
out.close();
if (in != null)
in.close();
if (clientSocket != null)
clientSocket.close();
}
}
}
Here is JFrame implementation:
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class View extends JFrame {
private JButton button;
private JTextField field;
private JPanel gui;
public View(final PrintWriter out, final BufferedReader in) throws IOException {
button = new JButton("Send");
field = new JTextField();
gui = new JPanel(new GridLayout(1, 0, 10, 10));
gui.add(button);
gui.add(field);
add(gui);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
out.println(field.getText());
try {
System.out.println(in.readLine());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}
Here is the server:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class SimpleServer extends Thread {
public static final int PORT = 8100;
private static ServerSocket serverSocket = null;
private Socket clientSocket = null;
public void run() {
String receive, answer;
try {
BufferedReader in = new BufferedReader(new InputStreamReader(
clientSocket.getInputStream()));
PrintWriter out = new PrintWriter(clientSocket.getOutputStream());
receive = in.readLine();
System.out.println("[server]" + receive);
answer = "hello " + receive;
out.println(answer);
out.flush();
} catch (IOException e) {
System.err.println("IO error \n" + e);
} finally {
try {
clientSocket.close();
} catch (IOException e) {
System.err.println("Close socket error \n" + e);
}
}
}
public SimpleServer() throws IOException {
while (true) {
serverSocket = new ServerSocket(PORT);
try {
clientSocket = serverSocket.accept();
new Thread(this).start();
} finally {
serverSocket.close();
}
}
}
public static void main(String[] args) throws IOException {
SimpleServer server = new SimpleServer();
}
}
Your connectToServer() method opens a connection, creates streams and ... then closes them before returning. So of course, the server sees the close straight away, and returns null on the first readLine() call.
I suspect that you may have copied the "close in a finally block" pattern without understanding what it means. So I shall explain:
This is the normal pattern:
InputStream is = null;
try {
is = new FileInputStream(someFile);
// read the stream
} finally {
if (is != null) {
is.close();
}
}
The purpose of the code above is to ensure that the InputStream is always closed. Or more precisely, that it is always closed before the try/finally exits.
This is generally a good thing. But if the purpose of your code is to open some streams that is going to be used after this bit of code completes, then closing the stream here is self defeating.
InputStream is = null;
try {
is = new FileInputStream(someFile);
} finally {
if (is != null) {
is.close();
}
}
// read the stream ... OOOPS! We've already closed it!!
So to take this back to your original code, you need to move the try/finally/close stuff to the run method, something along these lines:
public void run() {
try {
connectToServer();
createAndShowGui();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (out != null)
out.close();
if (in != null)
in.close();
if (clientSocket != null)
clientSocket.close();
}
}
You should also catch and (probably) ignore IOException that might be thrown by each close() call.
Javadoc for BufferedReader.readLine()
doesn't say anything like that:
Returns:
A String containing the contents of the line, not including
any line-termination characters, or null if the end of the stream has been reached
In your code you are opening a connection in connectToServer() and closing it, so server sees the end of stream