I'm continuing work on an android app for my coworkers. I've gotten past the errors in my code, but a new problem has arisen. The server program is meant to read from a text file and send the data to an android app, which interprets the data and organizes it into a listview.
This is the code:
Bserver:
package beaconserver;
import java.io.*;
import java.net.*;
public class Bserver {
static ServerSocket Sock = null;
static Socket server = null;
public static void main(String[] args) {
BufferedReader in = null;
PrintWriter Out = null;
String ok;
try{
System.out.println("Waiting for connection");
while(true){
Sock = new ServerSocket(8006);
server = Sock.accept();
in = new BufferedReader(new InputStreamReader(server.getInputStream()));
Out = new PrintWriter(server.getOutputStream());
String input = null;
Bfile file = new Bfile();
String[] companies = file.get();
System.out.println("starting send");
while(true){
System.out.println("in the while loop");
ok=in.readLine();
Bprotocol protocol = new Bprotocol();
input = protocol.sendMessage(ok, companies );
Out.write(input);
if(input.equals("end")){
break;
}
}
System.out.println("out of the while loop");
Out.close();
in.close();
server.close();
Sock.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Bprotocol:
public class Bprotocol {
static String output = null;
static int count = 0;
public String sendMessage(String ok, String[] file){
if(ok!=null && count<file.length){
System.out.println(count+1 + "of" + file.length);
output = file[count];
count++;
}else if(ok==null && count<file.length){
output=null;
}else if (count==file.length){
output = "end";
}
return output;
}
}
Bfile:
package beaconserver;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
public class Bfile {
static String[] filenames;
static BufferedReader Br = null;
static String names = null;
static ArrayList<String> Names = new ArrayList<String>();
public String[] get(){
try {
Br = new BufferedReader(new FileReader("/home/kyle/Documents/names.txt"));
} catch (FileNotFoundException e) {
System.out.println("file not found");
e.printStackTrace();
}
try {
while(Br.ready()){
names = Br.readLine();
Names.add(names);
}
Br.close();
} catch (IOException e) {
System.out.println("IOexception");
e.printStackTrace();
}
filenames = new String[Names.size()];
filenames = Names.toArray(filenames);
return filenames;
}
}
MainActivity: android
package com.AWS.beacon;
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 java.util.ArrayList;
import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity{
TextView response;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
response = (TextView) this.findViewById(R.id.textView2);
new GetNames(this).execute();
}
}
class GetNames extends AsyncTask<Void,String,Void>{
ArrayList<String> names = new ArrayList<String>();
PrintWriter out = null;
BufferedReader in = null;
Socket sock = null;
int L = 0;
String T = null;
static String[] companies = null;
String fromserver;
public MainActivity GetNamescontext =null;
public GetNames (MainActivity context){
GetNamescontext = context;
}
#Override
protected void onPreExecute(){
super.onPreExecute();
TextView prog = (TextView) GetNamescontext.findViewById(R.id.textView2);
prog.setText("Connecting");
}
#Override
protected Void doInBackground(Void... params) {
try {
sock = new Socket("elvishknight1.noip.me", 8006);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
out = new PrintWriter(sock.getOutputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
out.write("ok");
while((fromserver=in.readLine())!=null){
if(fromserver.equals("end")){
break;
}
T = in.readLine();
names.add(T);
}
out.close();
in.close();
sock.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result){
super.onPostExecute(result);
companies = names.toArray(new String[names.size()]) ;
Intent i = new Intent(GetNamescontext, MainScreen.class);
GetNamescontext.startActivity(i);
}
}
the program has some Sytsem.out.println commands for debugging. the problem is the program gets stuck on "in the while loop" and stops there. No errors, no logcat, nothing. I'm not sure what the problem could be. Could you guys help me out on this.
Thanks
You should add Out.flush() after Out.write(input);
When to use flush method and why do we use it?
this is used when there needs to be synchronous sending
for example you have a duplex (2-way) connection and you just sent a message and now need to wait for the reply on it, without flush a buffered outputstream might hold it until the buffer fills up (deadlock)
Temp Solution : i suppose you have defined in project's manifest that you need the internet permission. See this link
In your client you use readLine(). Therefore the server should write lines. Lines end with a \n. Especially send "end\n".
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 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 am doing java server on my pc and having my android device connect to it. I can connect it but it disconnects as soon as it connects. I am sure there is something I need to do on the android side but I am little lost on it. I have the internet permission so that is fine.
Also ignore the commented code I was sending image from my android to pc. Also ignore the savebitmap and take screenshot I don't think its affecting the connection if its not being called.
Java Server:
import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import javax.swing.*; //access JFrame
import javax.swing.text.html.HTMLDocument.Iterator;
import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.*;
public class tcpmain {
BufferedReader in;
static final int PORT = 9000;
public static void main(String[] args) {
// TODO Auto-generated method stub
//lines to make the gui frame
JFrame mainframe = new JFrame();
mainframe.setTitle("TCP Listener");
mainframe.setSize(600,800);
mainframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainframe.setVisible(true);
ServerSocket serverSocket = null;
Socket socket = null;
try{
serverSocket = new ServerSocket(PORT);
//Receive code
/*int filesize=450660;
int bytesRead;
int current=0;
//receive file
byte [] mybytearray = new byte [filesize];
InputStream is = srsvsock.getInputStream();
FileOutputStream fos = new FileOutputStream("C:\\Users\\Andy\\Desktop\\testimage.jpg");
BufferedOutputStream bos = new BufferedOutputStream(fos);
bytesRead = is.read(mybytearray,0,mybytearray.length);
current = bytesRead;*/
/*do{
bytesRead =
is.read(mybytearray, current, (mybytearray.length-current));
if(bytesRead >= 0) current += bytesRead;
} while(bytesRead > -1);
bos.write(mybytearray, 0, current);
bos.flush();*/
}
catch(Exception e){
e.printStackTrace();
}
while (true) {
try {
socket = serverSocket.accept();
JOptionPane.showMessageDialog(null, "Client connected", "ALERT", JOptionPane.INFORMATION_MESSAGE);
} catch (IOException e) {
System.out.println("I/O error: " + e);
}
// new threa for a client
new EchoThread(socket).start();
if ( socket != null && !socket.isClosed() ){
try {
socket.close();
JOptionPane.showMessageDialog(null, "Client Disconnected", "ALERT", JOptionPane.INFORMATION_MESSAGE);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
client handler for java server
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;
public class EchoThread extends Thread {
protected Socket socket;
public EchoThread(Socket clientSocket){
this.socket = clientSocket;
}
public void run(){
InputStream inp = null;
BufferedReader brinp = null;
DataOutputStream out = null;
try{
inp = socket.getInputStream();
brinp = new BufferedReader(new InputStreamReader(inp));
out = new DataOutputStream(socket.getOutputStream());
}catch(Exception e){
return;
}
String line;
while(true){
try{
line = brinp.readLine();
if ((line == null) || line.equalsIgnoreCase("QUIT")){
socket.close();
return;
}else{
out.writeBytes(line+ "\n\r");
out.flush();
}
}catch(Exception e){
e.printStackTrace();
return;
}
}
}
}
Here is android client:
package com.example.tcpsocket;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import android.os.Bundle;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity {
private Socket socket;
private static final int SERVERPORT = 9000;
private static final String SERVER_IP = "192.168.1.113";
Bitmap bitmap;
File imagePath;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnconnect = (Button)findViewById(R.id.button1);
btnconnect.setOnClickListener(connect);
}
private OnClickListener connect = new OnClickListener(){
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
//Bitmap bitmap = takeScreenshot();
// saveBitmap(bitmap);
new Thread(new clienthread()).start();
}
};
public Bitmap takeScreenshot() {
View rootView = findViewById(android.R.id.content).getRootView();
rootView.setDrawingCacheEnabled(true);
return rootView.getDrawingCache();
}
public void saveBitmap(Bitmap bitmap){
File imagePath = new File("sdcard/screenshot.jpg");
FileOutputStream fos;
try {
fos = new FileOutputStream(imagePath);
bitmap.compress(CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
new Thread(new clienthread()).start();
} catch (FileNotFoundException e) {
Log.e("GREC", e.getMessage(), e);
} catch (IOException e) {
Log.e("GREC", e.getMessage(), e);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
class clienthread implements Runnable {
#Override
public void run() {
// TODO Auto-generated method stub
try{
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
/*File imagePath = new File("sdcard/screenshot.jpg");
byte[] mybytearray = new byte[450560];
FileInputStream fis = new FileInputStream(imagePath);
BufferedInputStream bis = new BufferedInputStream(fis);
bis.read(mybytearray,0,mybytearray.length);
OutputStream os = socket.getOutputStream();
os.write(mybytearray,0,mybytearray.length);
os.close();*/
}
catch(Exception e){
}
}
}
}
Here:
new EchoThread(socket).start();
if ( socket != null && !socket.isClosed() ){
try {
socket.close();//Don't do this here!!!!!!
JOptionPane.showMessageDialog(null, "Client Disconnected", "ALERT", JOptionPane.INFORMATION_MESSAGE);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
You shouldn't close your socket after you started your Thread. The closing of the socket should be the job of the EchoThread after you finished communicating with it. You can insert this line at the end of run() method socket.close(); so it closes itself when you're done.
Looks like it is most likely due to this line:
if ( socket != null && !socket.isClosed() ){
If your socket was previously opened and you passed if off to the thread to handle, the socket would still be open and socket.isClosed() will return false and you'll immediately close the socket and clean it up in your main thread.
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
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.