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.
Related
I'm trying to create a server/client for the purpose of chatting. I start the server which waits for a client to connect, the client connects, but it gets stuck waiting for the client to send the username.
Here is the server:
package chat_server;
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.List;
public class Chat_Server {
private ServerSocket ss;
private Socket connection;
private List<ClientT> users;
private static int usersNumber;
public Chat_Server() {
users = new ArrayList<ClientT>();
usersNumber = 1;
try {
ss = new ServerSocket(2016);
} catch (IOException e) {
e.printStackTrace();
System.err.println(3);
}
}
public void acceptRequests() throws IOException {
while (true) {
try {
connection = ss.accept();
ClientT ct = new ClientT(connection);
users.add(ct);
System.out.print("Connected users: ");
for(int i = 0; i < users.size(); i++)
System.out.print(users.get(i) + " ");
System.out.println();
ct.start();
} catch (IOException e) {
System.out.println("Could not accept connection from client: "
+ e);
System.err.println(4);
}
}
}
}
class ClientT extends Thread {
private Socket s;
private BufferedReader in;
private DataOutputStream out;
private String userName = "a";
private String message;
int userNr;
public ClientT(Socket _s) {
this.s = _s;
userNr = usersNumber++;
System.out.println("In client: s = " + s + " userNr = " + userNr);
try {
System.out.println("Creating 'in' and 'out' objects");
out = new DataOutputStream(s.getOutputStream());
in = new BufferedReader(new InputStreamReader(
s.getInputStream()));
System.out.println("Catching username...");
**//--it gets stuck here--**
userName = (String) in.readLine();
System.out.println(userName + " connected...");
} catch (IOException e) {
e.printStackTrace();
System.err.println(1);
}
}
public void run() {
System.out.println("In ClientT run...");
while (true) {
try {
message = in.readLine();
System.out.println("Message: " + message);
System.out.println("Notifying all clients!");
messageNotifyAll(message);
} catch (IOException e) {}
}
}
}
public static void main(String[] args) throws IOException {
Chat_Server cs = new Chat_Server();
System.out.println("Accepting requests...");
cs.acceptRequests();
}
}
And here the the client:
package chatClient;
import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.swing.*;
#SuppressWarnings("serial")
public class Client extends JFrame {
private JTextArea textArea;
private JScrollPane scrollPane;
private JPanel panelButtons;
private JPanel panelList;
private JButton send;
private JButton disconnect;
#SuppressWarnings("rawtypes")
private JList userList;
private JLabel connectedUsers;
private JTextField text;
private JButton sendMessage;
private String name;
private Socket s;
BufferedReader in;
DataOutputStream out;
#SuppressWarnings("rawtypes")
public Client(String _name) throws InterruptedException {
System.out.println("Loading GUI...");
//GUI left out
System.out.println("Loading GUI finished...");
connectToServer();
}
public void connectToServer() throws InterruptedException {
try {
textArea.append("Connecting to server...\n");
s = new Socket("localhost", 2016);
textArea.append("Connected to " + s.getInetAddress() + ":" + s.getPort() +" as " + name + "...");
in = new BufferedReader(new InputStreamReader(s.getInputStream()));
out = new DataOutputStream(s.getOutputStream());
new waitForMessage().start();
out.writeBytes(name);
} catch (UnknownHostException e) {
textArea.append("Server not running!");
// e.printStackTrace();
} catch (IOException e) {
textArea.append(e + "\n");
try {
disconnectFromServer();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
public void disconnectFromServer() throws IOException {
s.close();
System.out.println("Disconnected!");
}
public class FrameExit extends WindowAdapter {
public void windowClosing(WindowEvent e) {
e.getWindow().dispose();
}
}
public class Disconnect implements ActionListener {
public void actionPerformed(ActionEvent e) {
try {
s.close();
System.out.println("Disconnecting...");
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
public class Send implements ActionListener {
public void actionPerformed(ActionEvent e) {
try {
System.out.println("Sending message: " + text.getText());
out.writeBytes(text.getText());
text.setText("");
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
public class waitForMessage extends Thread {
#Override
public void run() {
System.out.println("Waiting for message!");
while (true) {
try {
String message = in.readLine();
System.out
.println("Message received! Displaying message in GUI!");
textArea.append(message);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
//I have a login GUI from where I start the Client
}
}
Any help would be appreciated!
Server side seems to expect a line to read, but there is no line break sent from the client side.
Also, consider adding out.flush() after you write, to ensure that the data is actually sent.
out.writeBytes(name + System.getProperty("line.separator"));
out.flush();
Note that you could use a PrintWriter instead, which has println methods to take care of new lines.
See : What is the Difference between PrintWriter and DataOutputStream?
I am trying to a simple client server chat application using Stream sockets and Swing. But it is not working as it should. Apparently the server just waits for connection and does not proceed.
I have three java files, Server.java , Client.java and ChatApp.java
Server.java
package com.htpj.networkingChatApp;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.EOFException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class Server extends JFrame {
private static final long serialVersionUID = 1L;
private JTextArea displayArea;
private JTextField messageEnterField;
private ServerSocket server;
private Socket connectionSocket;
private ObjectInputStream input;
private ObjectOutputStream output;
private int counter = 1;
protected void serverGui() {
messageEnterField = new JTextField();
setMessageEnterFieldEditable(false);
messageEnterField.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
sendDataToClient(e.getActionCommand());
}
});
add(messageEnterField, BorderLayout.SOUTH);
displayArea = new JTextArea();
add(new JScrollPane(displayArea), BorderLayout.CENTER);
displayArea.setEditable(false); // display area is never editable
setSize(500, 500);
setLocationRelativeTo(null);
setTitle("Chat Server");
setVisible(true);
}
protected void runServer() {
try {
server = new ServerSocket(2000, 100);
while (true) {
try {
waitForConnection(); // wait for a connection
getStreams(); // get input and output streams
processConnection(); // process connections
} catch (EOFException e) {
displayMessage("\n server terminated the connection");
} finally {
closeConnection();
++counter;
}
}
} catch (IOException e) {
e.printStackTrace();
}
} // ENDOF method runServer
private void waitForConnection() {
try {
displayMessage("Waiting for Connection\n");
connectionSocket = server.accept();
displayMessage("Connection" + counter + "received from: " + connectionSocket.getInetAddress() + "port: "
+ connectionSocket.getPort());
} catch (IOException e) {
e.printStackTrace();
}
} // ENDOF method waitForConnection
private void getStreams() throws IOException {
output = new ObjectOutputStream(connectionSocket.getOutputStream());
output.flush(); // flush output buffer to send header information
input = new ObjectInputStream(connectionSocket.getInputStream());
displayMessage("\n Got I/O Streams \n");
} // ENDOF getStreams method
private void processConnection() throws IOException {
String message = null;
sendDataToClient("Connection Successful \n");
setMessageEnterFieldEditable(true); // enable server to type message
do {
try {
message = (String) input.readObject();
displayMessage("\n" + message);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} while (!message.equals("CLIENT >> TERMINATE"));
} // ENDOF processConnection method
private void closeConnection() {
displayMessage("\n closing connection \n");
setMessageEnterFieldEditable(false);
try {
output.close();
input.close();
connectionSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
} // ENDOF closeConnection method
private void sendDataToClient(String messageFromServer) {
try {
output.writeObject("SERVER>> " + messageFromServer);
output.flush(); // flush output to client
} catch (IOException e) {
e.printStackTrace();
}
} // ENDOF sendDataToClient method
private void displayMessage(String showMessage) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
displayArea.append(showMessage);
}
});
} // ENDOF method displayMessage
private void setMessageEnterFieldEditable(final boolean isEditable) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
messageEnterField.setEditable(isEditable);
}
});
}
} // ENDOF class server
Client.java
package com.htpj.networkingChatApp;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.EOFException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class Client extends JFrame {
private static final long serialVersionUID = 1L;
private JTextField messageEnterField;
private JTextArea displayArea;
private String chatHost;
private Socket clientSocket;
private ObjectInputStream input;
private ObjectOutputStream output;
private String message = "";
public Client(String host) {
this.chatHost = host;
}
protected void clientGui() {
messageEnterField = new JTextField();
setMessageEnterFieldEditable(false);
messageEnterField.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
sendDataToServer(e.getActionCommand());
}
});
add(messageEnterField, BorderLayout.SOUTH);
displayArea = new JTextArea();
add(new JScrollPane(displayArea), BorderLayout.CENTER);
displayArea.setEditable(false);
setTitle("Chat Client");
setSize(500, 500);
setLocationRelativeTo(null);
setVisible(true);
} // END OF clientGui method
// connect to the server and process message from server
protected void runClient() throws UnknownHostException, IOException, ClassNotFoundException {
// connect to server, get Streams, process connection
try {
connectToServer();
getStreams();
processConnection();
} catch (EOFException e) {
displayMessage("\n client closed the connection");
} finally {
closeConnection();
}
}
private void connectToServer() throws UnknownHostException, IOException {
displayMessage("Attempting Connection to Server: \n");
clientSocket = new Socket(InetAddress.getByName(chatHost), 2000);
displayMessage(
"Connected to: " + clientSocket.getInetAddress().getHostName() + "on Port : " + clientSocket.getPort());
} // END OF method connectToServer
private void getStreams() throws IOException {
output = new ObjectOutputStream(clientSocket.getOutputStream());
output.flush();
input = new ObjectInputStream(clientSocket.getInputStream());
displayMessage("\n Got I/O stream \n ");
} // END OF getStreams method
private void processConnection() throws ClassNotFoundException, IOException {
displayMessage("\n connected to server\n");
setMessageEnterFieldEditable(true);
do {
message = (String) input.readObject();
displayMessage("\n" + message);
} while (!message.equals("SERVER>> TERMINATE"));
} // end of processConnection method
private void closeConnection() throws IOException {
displayMessage("\n closing connection ");
input.close();
output.close();
clientSocket.close();
setMessageEnterFieldEditable(false);
} // end of closeConnection method
private void displayMessage(final String messageToShow) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
displayArea.append(messageToShow);
}
});
} // end of displayMessage method
private void sendDataToServer(String messageToServer) {
try {
output.writeObject(messageToServer);
output.flush();
} catch (IOException e) {
e.printStackTrace();
}
} // end of sendDataToServer method
private void setMessageEnterFieldEditable(final boolean isEditable) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
messageEnterField.setEditable(isEditable);
}
});
}
}
ChatApp.java
package com.htpj.networkingChatApp;
import java.io.IOException;
public class ChatApp{
public static void main(String[] args) {
Server chatServer = new Server();
Client chatClient = new Client("127.0.0.1");
chatServer.serverGui();
chatClient.clientGui();
chatServer.runServer();
try {
chatClient.runClient();
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
}
}
}
I create chat app one to one by using Java programming language
I faced issue: client can't send a new message until he receives a message from the server.
You should have a multithreaded application.
The client will run 2 threads:
1) Sender thread which will run on send button. You can every time create a new instance of this thread on clicking send button.
2) The receiver thread will keep on running continuously and check the stream for any message. Once it gets a message on stream it will write the same on console.
Will update you shortly with the code.
Thanks
Written this code long back similarly you can write server using other port
package com.clients;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
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.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class ClientFullDuplex extends JFrame implements ActionListener {
private JFrame jframe;
private JPanel jp1, jp2;
private JScrollPane jsp;
private JTextArea jta;
private JTextField jtf;
private JButton send;
private Thread senderthread;
private Thread recieverthread;
private Socket ds;
private boolean sendflag;
public static void main(String[] args) {
try {
ClientFullDuplex sfd = new ClientFullDuplex();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public ClientFullDuplex() throws UnknownHostException, IOException {
initGUI();
ds = new Socket("127.0.0.1", 1124);
initNetworking();
}
public void initGUI() {
jframe = new JFrame();
jframe.setTitle("Client");
jframe.setSize(400, 400);
jp1 = new JPanel();
jta = new JTextArea();
jsp = new JScrollPane(jta);
jtf = new JTextField();
send = new JButton("Send");
send.addActionListener(this);
jp1.setLayout(new GridLayout(1, 2, 10, 10));
jp1.add(jtf);
jp1.add(send);
jframe.add(jp1, BorderLayout.SOUTH);
jframe.add(jsp, BorderLayout.CENTER);
jframe.setVisible(true);
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jta.append("hello client");
}
#Override
public synchronized void addWindowListener(WindowListener arg0) {
// TODO Auto-generated method stub
super.addWindowListener(arg0);
new WindowAdapter() {
#Override
public void windowClosing(WindowEvent arg0) {
// TODO Auto-generated method stub
if (ds != null)
try {
ds.close();
System.exit(0);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
}
public void initNetworking() {
try {
recieverthread = new Thread(r1);
recieverthread.start();
} catch (Exception e) {
e.printStackTrace();
}
}
Runnable r1 = new Runnable() {
#Override
public void run() {
try {
System.out.println(Thread.currentThread().getName()
+ "Reciver Thread Started");
recieveMessage(ds);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
Runnable r2 = new Runnable() {
#Override
public void run() {
try {
System.out.println(Thread.currentThread().getName()
+ "Sender Thread Started");
sendMessage(ds);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
public void recieveMessage(Socket rms) throws IOException {
while (true) {
System.out.println(Thread.currentThread().getName()
+ "Reciver Functionality");
BufferedReader br = new BufferedReader(new InputStreamReader(
rms.getInputStream()));
String line = br.readLine();
System.out.println(line);
jta.append("\nServer:"+line);
}
}
public void sendMessage(Socket sms) throws IOException {
System.out.println(Thread.currentThread().getName()
+ "Sender Functionality");
PrintWriter pw = new PrintWriter(sms.getOutputStream(), true);
String sline = jtf.getText();
System.out.println(sline);
pw.println(sline);
jtf.setText("");
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if (e.getSource() == send) {
senderthread = new Thread(r2);
senderthread.start();
}
}
}
This is the code I copied and edited from your earlier post.
The problem is that the input stream from socket is blocking. So my suggestion is to read up on async sockets in java and refactor the code below.
next to that it isn't that difficult to edit posts.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Server {
public static void main(String[] args) {
Server chatServer = new Server(5555);
System.out.println("###Start listening...###");
chatServer.startListening();
chatServer.acceptClientRequest();
}
private ServerSocket listeningSocket;
private Socket serviceSocket;
private int TCPListeningPort;
private ArrayList<SocketHanding> connectedSocket;
public Server(int TCPListeningPort)
{
this.TCPListeningPort = TCPListeningPort;
connectedSocket = new ArrayList<SocketHanding>();
}
public void startListening()
{
try
{
listeningSocket = new ServerSocket(TCPListeningPort);
}
catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void acceptClientRequest()
{
try
{
while (true)
{
serviceSocket = listeningSocket.accept();
SocketHanding _socketHandling = new SocketHanding(serviceSocket);
connectedSocket.add(_socketHandling);
Thread t = new Thread(_socketHandling);
t.start();
System.out.println("###Client connected...### " + serviceSocket.getInetAddress().toString() );
}
}
catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
class SocketHanding implements Runnable
{
private Socket _connectedSocket;
private PrintWriter socketOut;
private InputStream socketIn;
private boolean threadRunning = true;
private String rmsg;
public SocketHanding(Socket connectedSocket) throws IOException
{
_connectedSocket = connectedSocket;
socketOut = new PrintWriter(_connectedSocket.getOutputStream(), true);
socketIn = _connectedSocket.getInputStream();
}
private void closeConnection() throws IOException
{
threadRunning = false;
socketIn.close();
socketOut.close();
_connectedSocket.close();
}
public void sendMessage(String message)
{
socketOut.println(message);
}
private String receiveMessage() throws IOException
{
String t = "";
if (_connectedSocket.getInputStream().available() > 0)
{
byte[] b = new byte[8192];
StringBuilder builder = new StringBuilder();
int bytesRead = 0;
if ( (bytesRead = _connectedSocket.getInputStream().read(b)) > -1 )
{
builder.append(new String(b, 0, b.length).trim());
}
t = builder.toString();
}
return t;
}
#Override
public void run()
{
while (threadRunning)
{
try
{
rmsg = receiveMessage();
System.out.println(rmsg);
if(rmsg.equalsIgnoreCase("bye"))
{
System.out.println("###...Done###");
closeConnection();
break;
}
else
{
String smsg = "";
BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in));
smsg = keyboard.readLine();
keyboard.close();
sendMessage("Server: "+smsg);
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
I didn't realize until now that my disconnect button on my program was failing. If I have 3 clients up, and any of them click disconnect, then only the last client gets disconnected. How do I select which instance I need to close? If out of the 3 users I want to remove the first one..
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;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
public class Server {
private Set<Socket> sockets = new HashSet<Socket>();
private Set<String> names = new HashSet<String>();
private Socket sock;
private static int port;
private Calendar cal = Calendar.getInstance();
private SimpleDateFormat date = new SimpleDateFormat("dd/mm/yyyy hh:mm:ss");
public Server(int input) {
port = input;
}
public static void main(String[] args) {
/*
* user defines port number, server initialized
*/
System.out.println("enter a port");
Scanner input = new Scanner(System.in);
port = input.nextInt();
new Server(port).go();
input.close();
}
public void go() {
try {
/*
* wait for connections, add connections to Set, setup streams per
* connection in new threads
*/
System.out.println("waiting for connetion");
#SuppressWarnings("resource")
ServerSocket serverSocket = new ServerSocket(port);
while (true) {
sock = serverSocket.accept();
sockets.add(sock);
Thread t = new Thread(new ClientHandler(sock));
t.start();
System.out.println("connected: " + sock.getInetAddress());
}
} catch (IOException ex) {
ex.printStackTrace();
System.out.println("server setup failed");
}
}
class ClientHandler implements Runnable {
/*
* client handler sets up streams
*/
private BufferedReader in;
private PrintWriter out;
private String name;
public ClientHandler(Socket sock) {
try {
in = new BufferedReader(new InputStreamReader(
sock.getInputStream()));
out = new PrintWriter(sock.getOutputStream(), true);
} catch (IOException e) {
e.printStackTrace();
System.out.println("stream setup failed");
}
}
#Override
public void run() {
/*
* First check if user exists, if true than close connection and
* warn user about name. Then relay message to all clients, if user
* DC's than remove the socket from the Set
*/
String message;
try {
name = in.readLine();
if (names.contains(name)) {
System.out.println("duplicate name detected, removing..");
out.println("choose new name and reconnect: "
+ sock.getInetAddress());
sock.close();
sockets.remove(sock);
} else {
names.add(name);
System.out.println("Users active: " + names);
shout("user: " + name + " connected!" + " from "
+ sock.getInetAddress());
}
while ((message = in.readLine()) != null) {
/*
* call method which checks if user tries to enter a command
* such as /laugh or /roll, otherwise relay the message to
* all clients
*/
swich(message);
}
} catch (IOException ex) {
System.out.println("user disconnected: " + name + " "
+ sock.getInetAddress());
shout("user disconnected: " + name + " "
+ sock.getInetAddress());
names.remove(name);
remove(sock);
}
}
public synchronized void shout(String message) {
// send message to all clients in Set
for (Socket sock : sockets) {
try {
PrintWriter writer = new PrintWriter(
sock.getOutputStream(), true);
writer.println(date.format(cal.getTime()) + " " + message
+ "\n");
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void swich(String message) throws IOException {
// check if user calls a chat command
// otherwise shout message to all clients
switch (message) {
case "/disconnect":
out.println("disconnected");
remove(sock);
break;
case "/laugh":
String[] laughs = { "HahHA!", "HAHAAH!!!!", "haaaaa!!!",
"hohohoohohahhaa!!!", "huehuehue!" };
shout(name + " " + laughs[(int) (Math.random() * 5)]);
break;
case "/roll":
shout(name + " rolls "
+ Integer.toString((int) ((Math.random() * 6) + 1)));
break;
case "kirby!":
shout("(>'-')> <('-'<) ^(' - ')^ <('-'<) (>'-')>");
break;
default:
shout(message);
System.out.println("client says : "
+ date.format(cal.getTime()) + message);
}
}
}
public void remove(Socket soc) {
try {
soc.close();
sockets.remove(soc);
} catch (IOException e) {
e.printStackTrace();
}
}
}
client:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class Client {
private JTextArea tArea;
private JTextField tField;
private JTextField portText;
private JTextField hostText;
private BufferedReader in;
private Socket sock;
private static PrintWriter out;
private static String name;
private String host;
private String port;
public static void main(String[] args) {
System.out.println("Enter username");
Scanner input = new Scanner(System.in);
name = input.nextLine();
input.close();
new Client().go();
}
public void go() {
/*
* build gui
*/
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame("hakobChat");
JPanel topPanel = new JPanel();
JLabel portLabel = new JLabel("port");
JLabel hostLabel = new JLabel("host");
portText = new JTextField(6);
hostText = new JTextField(12);
JButton connect = new JButton("connect");
connect.addActionListener(new connectListener());
JButton disconnect = new JButton("disconnect");
disconnect.addActionListener(new disconnectListener());
tField = new JTextField(30);
tField.addActionListener(new sendListener());
tArea = new JTextArea(30, 50);
tArea.setEditable(false);
tArea.setLineWrap(true);
JScrollPane tScroll = new JScrollPane(tArea,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
JButton button = new JButton("send");
button.addActionListener(new sendListener());
topPanel.add(hostLabel);
topPanel.add(hostText);
topPanel.add(portLabel);
topPanel.add(portText);
topPanel.add(connect);
topPanel.add(disconnect);
frame.setSize(300, 500);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(topPanel, BorderLayout.NORTH);
frame.getContentPane().add(tScroll, BorderLayout.CENTER);
frame.getContentPane().add(tField, BorderLayout.SOUTH);
frame.getContentPane().add(button, BorderLayout.EAST);
frame.pack();
}
});
}
public void setupNetwork(String host, int port) {
/*
* setup in and out stream send user name to server to check if
* duplicate start thread for incoming messages
*/
try {
sock = new Socket(host, port);
in = new BufferedReader(
new InputStreamReader(sock.getInputStream()));
out = new PrintWriter(sock.getOutputStream(), true);
out.println(name);
showMessage("Connected!");
showMessage("enter /laugh or /roll or kirby! for some fun!");
Thread t = new Thread(new IncomingReader());
t.start();
} catch (IOException ex) {
ex.printStackTrace();
showMessage("please enter valid network");
}
}
class IncomingReader implements Runnable {
// receive messages from server
public void run() {
try {
String message = null;
while ((message = in.readLine()) != null) {
showMessage(message + "\n");
}
} catch (Exception e) {
e.printStackTrace();
showMessage("choose new name and reconnect please");
}
}
}
public synchronized void sendMessage(String message) {
try {
switch (message) {
case "/laugh":
out.println("/laugh");
break;
case "/roll":
out.println("/roll");
break;
case "kirby!":
out.println("kirby!");
break;
default:
out.println("(" + name + ")" + ": " + message);
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("fail send message");
}
}
public void showMessage(final String message) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
tArea.append(message + "\n");
tArea.setCaretPosition(tArea.getDocument().getLength());
// SetCaretPosition forces autos scroll
}
});
}
class sendListener implements ActionListener {
// listens for user to trying to send a message
public void actionPerformed(ActionEvent ev) {
sendMessage(tField.getText());
tField.setText("");
}
}
class disconnectListener implements ActionListener {
public void actionPerformed(ActionEvent ev) {
try {
out.println("/disconnect");
} catch (NullPointerException e) {
showMessage("not connected");
}
}
}
class connectListener implements ActionListener {
public void actionPerformed(ActionEvent ev) {
host = hostText.getText();
port = portText.getText();
if (!host.equals("") && !port.equals("") && port.matches("[1-9]+")) {
// make sure user enters valid inputs
// before setting up network
setupNetwork(host, Integer.parseInt(port));
} else {
showMessage("enter valid network credentials");
}
}
}
}
Also, how do I avoid this "#SuppressWarnings("resource")". If I don't have this eclipse provided warning than the serverSocket is underlined yellow.
You need to save a the Socket used for the client inside of the ClientHandler.
You can do this by simply adding a
private Socket sock;
inside of ClientHandler, and adding:
this.sock = sock;
inside of its constructor.
Currently you're using the Socket saved in the server, which will always be the socket of the last client that connected, rather than the Socket belonging to the current client.
This is just a scoping problem. The Socket sock member shouldn't be part of the Server class. It should be part of the ClientHandler class. One per client.
As I am learning java socket, I've made a functionnal but very simple chat in two frames : one client and one server. The app is only local and works. But it does not stop when I close windows (though I added WindowListener to both frame classes) : what's wrong ?
Don't forget to run the server first, and then the client : both frames will be visibles only after the client connection.
Here is SimpleSocketFrame.java (base class for both frames) :
package com.loloof64.java_se.simple_socket;
import java.awt.GridLayout;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public abstract class SimpleSocketFrame extends JFrame {
public SimpleSocketFrame() {
setTitle(getFrameTitle());
setLayout(new GridLayout(0, 1));
messageToAddField = new JTextField(30);
messageToAddField.addKeyListener(new KeyAdapter() {
#Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER){
if ( ! messageToAddField.getText().isEmpty()) {
addMessage(messageToAddField.getText());
messageToAddField.setText("");
}
}
}
});
printedMessagesArea = new JTextArea(10,30);
printedMessagesArea.setEditable(false);
add(messageToAddField);
add(printedMessagesArea);
pack();
}
protected abstract void addMessage(String s);
protected abstract String getFrameTitle();
private static final long serialVersionUID = -5861605385948623162L;
protected JTextArea printedMessagesArea;
private JTextField messageToAddField;
}
Here is the server app class : SimpleSocketServer.java
package com.loloof64.java_se.simple_socket;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import javax.swing.JOptionPane;
public class SimpleSocketServer extends SimpleSocketFrame {
public SimpleSocketServer(){
super();
setTitle("Simple Server");
try {
serverSocket = new ServerSocket(12345);
relatedSocket = serverSocket.accept();
outStream = new PrintStream(relatedSocket.getOutputStream());
isr = new InputStreamReader(relatedSocket.getInputStream());
inStream = new BufferedReader(isr);
final InStreamRunnable inStreamRunnable = new InStreamRunnable();
Thread inStreamReaderThread = new Thread(inStreamRunnable);
addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent evt) {
try {
inStream.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
isr.close();
} catch (IOException e) {
e.printStackTrace();
}
outStream.close();
try {
relatedSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
inStreamRunnable.stop();
System.exit(0);
}
});
inStreamReaderThread.start();
} catch (IOException e) {
JOptionPane.showMessageDialog(this, "Could not create the server !!!",
"Fatal error", JOptionPane.ERROR_MESSAGE);
System.exit(1);
e.printStackTrace();
}
}
private class InStreamRunnable implements Runnable {
#Override
public void run() {
while (weMustGoOn){
String line;
try {
line = inStream.readLine();
printedMessagesArea.setText(printedMessagesArea.getText()+line+"\n");
} catch (IOException e) {
}
}
}
public void stop(){
weMustGoOn = false;
}
private boolean weMustGoOn = true;
}
#Override
protected void addMessage(String s) {
s = "Serveur> "+s;
outStream.println(s);
printedMessagesArea.setText(printedMessagesArea.getText()+"Client> "+s+"\n");
}
#Override
protected String getFrameTitle() {
return "Simple Server";
}
public static void main(String[] args) {
new SimpleSocketServer().setVisible(true);
}
private static final long serialVersionUID = 4288994465786972478L;
private Socket relatedSocket;
private ServerSocket serverSocket;
private PrintStream outStream;
private InputStreamReader isr;
private BufferedReader inStream;
}
Here is the client class : SimpleSocketClient.java
package com.loloof64.java_se.simple_socket;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.Socket;
import javax.swing.JOptionPane;
public class SimpleSocketClient extends SimpleSocketFrame {
public SimpleSocketClient(){
try {
socket = new Socket(InetAddress.getLocalHost(), 12345);
outStream = new PrintStream(socket.getOutputStream());
isr = new InputStreamReader(socket.getInputStream());
inStream = new BufferedReader(isr);
final InStreamRunnable inStreamRunnable = new InStreamRunnable();
Thread inStreamReaderThread = new Thread(inStreamRunnable);
addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent evt) {
try {
inStream.close();
} catch (IOException e2) {
e2.printStackTrace();
}
try {
isr.close();
} catch (IOException e1) {
e1.printStackTrace();
}
outStream.close();
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
inStreamRunnable.stop();
System.exit(0);
}
});
inStreamReaderThread.start();
} catch (IOException e) {
JOptionPane.showMessageDialog(this, "Could not create the client !!!",
"Fatal error", JOptionPane.ERROR_MESSAGE);
System.exit(1);
e.printStackTrace();
}
}
public static void main(String[] args) {
new SimpleSocketClient().setVisible(true);
}
private class InStreamRunnable implements Runnable {
#Override
public void run() {
while (weMustGoOn){
String line;
try {
line = inStream.readLine();
printedMessagesArea.setText(printedMessagesArea.getText()+line+"\n");
} catch (IOException e) {
}
}
}
public void stop(){
weMustGoOn = false;
}
private boolean weMustGoOn = true;
}
#Override
protected void addMessage(String s) {
s = "Client> "+s;
outStream.println(s);
printedMessagesArea.setText(printedMessagesArea.getText()+s+"\n");
}
#Override
protected String getFrameTitle() {
return "Simple Client";
}
private static final long serialVersionUID = 5468568598525947366L;
private Socket socket;
private PrintStream outStream;
private InputStreamReader isr;
private BufferedReader inStream;
}
The program doesn't stop as you're attempting to close the network input Readers when closing a JFrame, which are blocking indefinitely. BufferedReader and InputStreamReader objects cannot close as the client thread is blocked in this readLine call which is waiting for a response from the server
line = inStream.readLine();
Comment out or remove:
inStream.close();
and
isr.close();
Just closing the Socket stream will suffice.
Aside: When interacting with Swing components for multi-threaded network applications, always use a SwingWorker. SwingWorkers are designed to interact correctly with Swing components.
You should add finally block after try and catch to close the socket and after that you can close your program by system exit method.