JAVA Chat app not working over internet - java

I created a chat app in Java it worked when i open server and clients on different terminals but same computer. Today i gave it to my friend to test it over internet and its not working(Connection timed out ,yes i am using muiltithreads). I have allowed port (i am using 4242) in my firewall and my friends. But still not working.
I have read couple of similar question asked on internet but each has different steps (none working) and also i am not getting all steps though.
Some said that router is hiding my ip address so i need to enable port forwarding (i dont know how) . Also there must be a way without it. Many software works like this but doesnt need us to enable port forwarding. Will using a mobile hotspot instead of modem work(I am so DUMB!).
i am noob in this area, studied networking in JAVA yesterday and made app yesterday night. Help me run my app over internet in simple language. Will be gratefull if it works without port forwarding and static ip address. Let me know if you need to see my code.
Server Side:
import java.io.*;
import java.net.*;
import java.util.*;
class DailyAdviceS
{
ArrayList<PrintWriter> Clients=new ArrayList<PrintWriter>();
Socket sock;
public static void main(String args[])
{
DailyAdviceS ad= new DailyAdviceS();
ad.go();
}
private void go()
{
try
{
ServerSocket server= new ServerSocket(4242);
InetAddress ip;
ip = InetAddress.getLocalHost();
System.out.println("Current IP address : " + ip.getHostAddress());
while(true)
{
sock=server.accept();
PrintWriter writer = new PrintWriter(sock.getOutputStream());
Clients.add(writer);
Thread foundR= new Thread(new nodeR(sock));
foundR.start();
System.out.println("got a connection");
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
private void SendAll(String Chat,String name)
{
Iterator it=Clients.iterator();
while(it.hasNext())
{
try
{
PrintWriter writer= (PrintWriter)it.next();
writer.println(name+" /t "+Chat);
writer.flush();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
class nodeR implements Runnable //recieve message from clients
{
private String hostName;
private BufferedReader reader;
public nodeR(Socket s)
{
try
{
String hostName = s.getInetAddress().getHostName();
System.out.println(hostName);
InputStreamReader in= new InputStreamReader(s.getInputStream());
reader = new BufferedReader(in);
}
catch(Exception e)
{
e.printStackTrace();
}
}
public void run()
{
String Message;
try
{
String Name=InetAddress.getLocalHost().getCanonicalHostName();
SendAll(Name+" Ready","");
while(true)
{
while ((Message=reader.readLine())!=null)
{
SendAll(Message,Name);
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
}
CLient Side:
import java.io.*;
import java.net.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import javax.swing.text.*;
class DailyAdvice
{
private JTextArea ar= new JTextArea(100,100);
private JTextField field = new JTextField(17);
private JButton button;
private Socket chat;
private InputStreamReader stream;
private BufferedReader reader;
private PrintWriter writer;
public static void main(String args[])
{
DailyAdvice ad= new DailyAdvice();
ad.setnw();
ad.go();
}
private void go()
{
JFrame frame= new JFrame("Chat with RedHead");
JPanel panel= new JPanel();
ar.setLineWrap(true);
ar.setWrapStyleWord(true);
ar.setEditable(false);
JScrollPane scroll= new JScrollPane(ar);
scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
panel.add(field);
DefaultCaret caret = (DefaultCaret) ar.getCaret();
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
button= new JButton("Send");
panel.add(button);
frame.getRootPane().setDefaultButton(button);
frame.add(scroll,BorderLayout.CENTER);
frame.add(panel,BorderLayout.SOUTH);
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
frame.setBounds(50,50,300,300);
frame.setVisible(true);
Runnable r= new Recieve();
Thread send= new Thread(new Send());
Thread recieve= new Thread(r);
send.start();
recieve.start();
}
private void setnw()
{
try
{
chat = new Socket("122.176.8.153",4242);
stream= new InputStreamReader(chat.getInputStream());
reader= new BufferedReader(stream);
writer = new PrintWriter(chat.getOutputStream());
System.out.println("connection established");
}
catch(Exception e)
{
e.printStackTrace();
}
}
class Send implements Runnable
{
public void run()
{
button.addActionListener(new timetosend());
}
class timetosend implements ActionListener
{
public void actionPerformed(ActionEvent ev)
{
try
{
String msg =field.getText();
writer.println(msg);
writer.flush();
}
catch (Exception ex)
{
ex.printStackTrace();
}
field.setText("");
}
}
}
class Recieve implements Runnable
{
public void run()
{
try
{
String input;
while ((input= reader.readLine())!=null)
{
String[] result=input.split("/t");
ar.append(result[0]+" : "+result[1]+'\n');
}
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
}
}

Please make sure your application is not using the private IP to connect to your server if accessing over the internet. you can check your PC's public IP from the site below which is currently allocated to your PC, and can use this in your client apps.
And also make sure you have configure the port in port forwarding in your switch/router and if it is not allowed by your ISP, you can use any port forwarding software on your PC to do that.
http://www.get-myip.com/

Related

Using JFrame from another class

Hi I'm small a little issue trying to append some text to a JTextArea from another class within the same package. Below is the main class that pertains to the JFrame:
public class Client extends JFrame{
//Static variables
private static final String host = "localhost";
private static final int portNumber = 4444;
//Variables
private String userName;
//JFrame Variables
private JPanel contentPanel;
private JTabbedPane panel_Social;
private JPanel jpanel_Social;
private JPanel jpanel_Chat;
private JTextArea textArea_Receive;
private JTextField textField_Send;
private JTextArea textArea_ClientList;
private JButton btn_Enter;
public JTextArea getTextArea_Receive(){
return this.textArea_Receive;
}
//Constructor
private Client(String userName, String host, int portNumber){
this.userName = userName;
this.serverHost = host;
this.serverPort = portNumber;
}
public void main(String args[]){
//Requests user to enter name
String readName = null;
Scanner scan = new Scanner(System.in);
System.out.println("Please enter username");
readName = scan.nextLine();
//Start client
Client client = new Client(readName, host, portNumber);
client.startClient(scan);
}
private void startClient(Scanner scan){
try{
//Create new socket and wait for network communication
Socket socket = new Socket(serverHost, serverPort);
Thread.sleep(1000);
//Create thread and start it
serverThread = new ServerThread(socket, userName);
Thread serverAccessThread = new Thread(serverThread);
serverAccessThread.start();
}
}
}
Below is the serverThread class
public class ServerThread implements Runnable{
private Socket socket;
private String userName;
private boolean isAlived;
private final LinkedList<String> messagesToSend;
private boolean hasMessages = false;
//Constructor
ServerThread(Socket socket, String userName){
this.socket = socket;
this.userName = userName;
messagesToSend = new LinkedList<String>();
}
public void run(){
try{
Client test1 = new Client();
JTextArea test2 = test1.getTextArea_Receive();
String test3 = "Hello World";
test2.append(test3);
} catch (IOException e){
}
}
I included test variables just to easily recreate the issue but whenever the append function is run nothing appears in the text area of the jFrame. In my scenario I'm having the client receive text from a server then append it to the text box.
BTW I'm using the IntelliJ GUI designer for the JFrame. I've only included code needed to recreate the problem. I'm still trying to create MCVE questions so feel free to let me know mistakes I made.
You should pass Client into ServerThread via the constructor. The Client you are instantiating within run() is not the same reference to the Client you created in main(). So your ServerThread class would be something like
ServerThread(Client client, Socket socket, String userName) {
this.client = client;
this.socket = socket;
this.userName = userName;
messagesToSend = new LinkedList<String>();
}
public void run() {
try
{
JTextArea test2 = this.client.getTextArea_Receive();
String test3 = "Hello World";
test2.append(test3);
}
catch (IOException e)
{}
}
Your startClient() method would be updated to something like this
private void startClient(Client client, Scanner scan)
{
try
{
//Create new socket and wait for network communication
Socket socket = new Socket(serverHost, serverPort);
Thread.sleep(1000);
//Create thread and start it
ServerThread serverThread = new ServerThread(client, socket, userName);
serverAccessThread.run();
}
}
All that being said,
I would recommend moving your main() out of Client and into a class that isn't so coupled to the Swing UI code. Something like this:
public class MySwingApplication {
private static final String host = "localhost";
private static final int portNumber = 4444;
public static void main(String[] args) {
// Requests user to enter name
// Start client
}
}
Your Client is then built more like an instance object
public class Client extends JFrame {
public JTextArea getTextArea_Receive(){
// Return the text area
}
// Constructor -- public to allow instantiation from main()
public Client(String userName, String host, int portNumber) {
// Do stuff
}
private void startClient(Scanner scan) {
// Show the JFrame on screen
// Spawn Server
}
}
the append function is run nothing appears in the text area of the jFrame
There's not enough information available in you question to ascertain why this might be happening, how ever, there are a number of important pieces of information you need to take into account.
Swing is single threaded and not thread safe
You want to, as much as possible, decouple of the code
Basically, the first point means that you shouldn't be running any long running or blocking processes within the Event Dispatching Thread AND you should not be modifying the UI (or any state the UI relies on) from outside the context of the Event Dispatching Thread
Start by taking a look at Concurrency in Swing for more details.
The second point means that, for even given part of your code, you want to be asking, "how hard would it be to replace it with some other implementation?" - If the amount of work scares you, then your code is probably to tightly coupled.
To that end, I started with...
public interface Client {
public void append(String message);
}
This is really basic, but it means that some component can send a message to some other component and neither should care about each other beyond this capability.
Next, I looked at ServerThread. Basically this class becomes responsible for the management of the Socket and delivery of the messages to the Client. Because of the requirements of Swing, I've used a SwingWorker. This allows me to run the Socket code on a background thread, but ensure that the messages are delivered to the Client within the context of the Event Dispatching Thread
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.util.List;
import javax.swing.SwingWorker;
public class ServerThread extends SwingWorker<Void, String> {
private String host;
private int port;
private Client client;
//Constructor
ServerThread(String host, int port, Client client) {
this.host = host;
this.port = port;
this.client = client;
}
#Override
protected void process(List<String> chunks) {
for (String message : chunks) {
client.append(message);
}
}
#Override
protected Void doInBackground() throws Exception {
try (Socket socket = new Socket(host, port)) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()))) {
String text = null;
while ((text = reader.readLine()) != null) {
System.out.println(text);
if (text.equals("<stop>")) {
break;
}
publish(text);
}
}
} catch (IOException exp) {
exp.printStackTrace();
publish("Failed to establish connection to " + host + ":" + port + " - " + exp.getMessage());
}
return null;
}
}
And then the actual UI client itself...
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
public class Main {
public static void main(String[] args) {
new Main();
}
//Constructor
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
ClientUI clientUI = new ClientUI();
ServerThread thread = new ServerThread("localhost", 4321, clientUI);
thread.execute();
JFrame frame = new JFrame("Client");
frame.add(clientUI);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class ClientUI extends JPanel implements Client {
private JTextArea ta;
public ClientUI() {
setLayout(new BorderLayout());
ta = new JTextArea(10, 20);
add(new JScrollPane(ta));
}
#Override
public void append(String message) {
ta.append(message + "\n");
}
}
}
Not much going on here
Finally, I wrote a simple Server test the code, which simply sends the current date/time as a String to the connected client.
When I say simple, I mean simple. This is intended, by design, to tell with a single client connection and is meant only for testing the above code
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.DateFormat;
import java.util.Date;
public class Server {
public static void main(String[] args) {
DateFormat format = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
try (ServerSocket server = new ServerSocket(4321)) {
Socket socket = server.accept();
System.out.println("Connected");
try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()))) {
while (true) {
System.out.println("Write >> ");
writer.write(format.format(new Date()));
writer.newLine();
writer.flush();
Thread.sleep(1000);
}
}
} catch (IOException | InterruptedException exp) {
exp.printStackTrace();
}
}
}
To test it all, start the Server and then run the Main class

Java - Iterate through IP Address List and call thread with IP Address as argument

I'm relatively new to Java and I'm writing an application to interrogate an Apache HTTP server's access_log file; with this, I want to submit the IP Addresses individually (probably via the Apache HTTPClient library) to another Java instance on another server (as the Web server does not have FTP enabled) to pull some log files. At the moment I've managed to bumble my way through modifying a 'tail -f' equivalent class to suit the programs needs and then manipulate that data to get the IP Addresses that I need to do something with - I even managed to make the 'tail' class threaded so it could address multiple periods of time!
With that said, I want to use a for loop to iterate through each entry in my computerRebootList String Array and with each address create a thread to perform some more work but all I can think of is this;
for (String tmpIpAddress : computerRebootList ) {
ComputerIpHandler handler = new ComputerIpHandler();
}
and then create another class named ComputerIpHandler like so;
public class KioskIpHandler implements Runnable {
static final Logger logger = LogManager.getLogger( ComputerIpHandler.class );
#Override public void run() {
//do some code
}
public static void main(String computerIp) {
Thread mainThread = new Thread(new ComputerIpHandler());
mainThread.start();
try {
logger.info("log some stuff");
mainThread.join();
logger.info("yay it's done");
}
catch (InterruptedException errInterrupted) {
logger.error(errInterrupted.getMessage());
logger.error(errInterrupted.getStackTrace());
}
}
}
I read somewhere about ensuring that I need to manage resource limitations so I would have to create a maximum number of threads - arguably I could send something like 10 IPs to this class and then have the rest of the addresses 'queue' until the one has returned... I'm just not confident or fluent enough to be able to conceptualise these ideas.
EDIT: I omitted that I am restricted to Java 1.6 as this is the maximum compatible version of the JRE that we can use on this server - not sure if that hinders this effort somewhat...
Can anyone point me in the right direction?
Check ScheduledThreadPoolExecutor and ScheduledExecutorService classes in package java.util.concurrent in java API. Those and some other classes in that package would manage all resources for you. They are available in java since version 1.5
I recommend using Java's built in FTP connection platform to make a thread for continually receiving data on a specified port, until it receives a termination key.
Basically, one class will create a ServerSocket (open socket on server) and upon connection with another socket (the client socket) it would create a new thread for receiving information.
public class Server {
public ServerSocket ss;
public Socket clientSocket;
public Thread receiveingThread;
public BufferedReader inFromClient = null;
public boolean running = false;
public Server(int port) {
try {
ss = new ServerSocket(port);
startReceiving();
} catch (Exception e) {
e.printStackTrace();
}
}
public synchronized void startReceiving() {
receiveingThread = new Thread("Recieve") {
public void run() {
String dataFromClient = new String("");
while (running) {
try {
inFromClient = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
dataFromClient = inFromClient.readLine();
} catch (Exception e) {
e.printStackTrace();
}
if (dataFromClient.equals("TERMINATOR_KEY") {
stopRecieving();
}
else if(!dataFromClient.equals("")) {
//add item to array
}
}
}
};
receiveingThread.start();
}
public synchronized void stopReceiving() {
try {
running = false;
receivingThread.join();
ss.close();
clientSocket.close();
} catch (Exception e) {
e.printStackTrace();
}
System.exit(0);
}
public static void main(String[] args) {
new Server(yourPortHere);
}
}
then the client class would look something like:
public class Client {
public Socket socket;
public Thread send;
public Client(string serverPublicIP, int port) {
try {
socket = new Socket(serverPublicIP, port);
send("some IP address");
} catch (Exception e) {
e.printStackTrace();
}
}
public void send(String toSend) {
send = new Thread("Send") {
public void run() {
PrintWriter outToServer;
try {
outToServer = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
outToServer.print(toSend);
outToServer.flush();
} catch (Exception e) {
e.printStackTrace();
}
finally {
outToServer.close();
}
}
};
send.start();
}
public static void main(String[] args) {
new Client("127.0.0.1", yourPortHere);
}
}
This is the link for the start of socket tutorials on the oracle site.
This is the Oracle Documentation for java.net.ServerSocket
This is the Oracle Documentation for java.net.Socket

Java NIO - SocketChannel.write() on server many times but Client only receive result once

I'm doing an exercise requires making a server - client chat program using Java Non-Blocking IO. At the moment, the way the program works is simple: when a client send a message to the server, the server (which already keep track of all the clients) echo the message back to all the clients.
This is my some parts of my server-side code:
public static ByteBuffer str_to_bb(String msg) {
try {
return encoder.encode(CharBuffer.wrap(msg));
} catch(Exception e) {
e.printStackTrace();
}
return null;
}
private static void broadcastMessage(String nickname, String message) {
System.out.println(">clientSocketChannels size " + clientSocketChannels.size());
Iterator clientSocketChannelsIterator = clientSocketChannels.iterator();
while (clientSocketChannelsIterator.hasNext()) {
SocketChannel sc = (SocketChannel) clientSocketChannelsIterator.next();
try {
ByteBuffer bb = str_to_bb(message);
System.out.println("bufferRemaining: " + bb.remaining()); // returns 2048
int writeResult = sc.write(bb);
System.out.println("writeResult: " + writeResult); // returns 2048
} catch (IOException e) {
e.printStackTrace();
}
}
}
The following is my client-side code:
import javax.swing.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
/**
* Created by ThaiSon on 7/6/2015.
*/
public class ChatRoomClientGUI {
private JTextArea textAreaMessages;
private JTextField textFieldMessage;
private JButton buttonSendMsg;
private JPanel jPanel1;
private JLabel txtFieldInfo;
private static InetAddress inetAddress;
private static final int PORT = 1234;
private static Socket socket = null;
private static Scanner input = null;
private static PrintWriter output = null;
private static ChatRoomClientGUI singleton;
public ChatRoomClientGUI() {
singleton = this;
buttonSendMsg.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
if (e.getButton() == MouseEvent.BUTTON1) {
String message = textFieldMessage.getText();
output.println(message);
textFieldMessage.setText("");
}
}
});
}
public static void main(String[] args) {
JFrame promptFrame = new JFrame();
Object nickname = JOptionPane.showInputDialog(promptFrame, "Enter your nickname:");
promptFrame.dispose();
JFrame frame = new JFrame("ChatRoomClientGUI");
frame.setContentPane(new ChatRoomClientGUI().jPanel1);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
System.out.println("> Client with nickname " + nickname);
try {
inetAddress = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
e.printStackTrace();
}
accessServer(nickname.toString());
}
private static void accessServer(String nickname) {
try {
socket = new Socket(inetAddress, PORT);
input = new Scanner(socket.getInputStream());
output = new PrintWriter(socket.getOutputStream(), true);
output.println(nickname); // Register nickname with the server
//TODO update the txtFieldInfo content
// Create a new thread to listen to InputStream event
InputStreamEvent inputStreamEvent = new InputStreamEvent(socket);
inputStreamEvent.start();
} catch (IOException e) {
e.printStackTrace();
}
}
private static void handleInputStream(){
String response = input.nextLine();
System.out.println("TODO " + response);
singleton.textAreaMessages.append(response + "\n");
}
static class InputStreamEvent extends Thread{
Socket socket;
public InputStreamEvent(Socket socket){
this.socket = socket;
}
public void run(){
try {
InputStream inputStream = socket.getInputStream();
byte[] buffer = new byte[2048];
int read;
while (true){
if(inputStream.available() > 0){
handleInputStream();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
The problem I'm facing with now is that when I use a client (which works well with the old multithreaded server) to send message to the server, the client only get return the first message it sends. All the next responses from the server is empty (the server does send back, but only an empty message).
So my attempts to debug includes:
check if the messages from the client has reach the server or not. They does.
log the buffer.remaining() and socketChannel.write(buffer) result as shown above, all the log result seems to be normal to me.
Hope you guys can help me with this.
This:
if(inputStream.available() > 0){
Get rid of this test. With it, your client is smoking the CPU. Without it, it will block in readLine() as God intended.
Are you sure your server is still sending lines? with line terminators? If it isn't, readLine() will block forever looking for one, until end of stream or an exception occurs.
I referred the code explain by EJP on this link Java NIO Server/Client Chat App - sending data only by closing the socket
it solves my problem. use this code
import java.nio.channels.SocketChannel;
import java.nio.channels.Selector;
import java.nio.ByteBuffer;
import java.io.IOException;
import java.util.Scanner;
import java.nio.channels.SelectionKey;
import java.net.InetSocketAddress;
public class Client {
public static void main(String args[]) {
try {
ByteBuffer buf = ByteBuffer.allocate(200);
Scanner scanner = new Scanner(System.in);
Selector selector = Selector.open();
SocketChannel socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_CONNECT|SelectionKey.OP_READ|SelectionKey.OP_WRITE);
boolean isConnected = socketChannel.connect(new InetSocketAddress("localhost", 5000));
if(isConnected) {
System.out.println("Connected, de-registering OP_CONNECT");
}
new Thread(new Runnable(){
private SocketChannel socketChannel;
private Selector selector;
public Runnable init(SocketChannel socketChannel, Selector selector) {
this.socketChannel = socketChannel;
this.selector = selector;
return this;
}
public void run() {
try {
ByteBuffer buf = ByteBuffer.allocate(200);
while(!Thread.interrupted()) {
int keys = selector.select();
if(keys > 0) {
for(SelectionKey key : selector.selectedKeys()) {
if(key.isConnectable()) {
boolean finishConnectResult = socketChannel.finishConnect();
socketChannel.register(this.selector, SelectionKey.OP_WRITE|SelectionKey.OP_READ);
System.out.println("Finished Connect : " + finishConnectResult);
}
if(key.isReadable()) {
int bytesRead = 0;
while((bytesRead = socketChannel.read(buf)) > 0) {
buf.flip();
while(buf.hasRemaining()) {
System.out.print((char)buf.get());
}
buf.clear();
}
if(bytesRead == -1) {
key.channel().close();
}
}
}
}
Thread.sleep(10);
}
} catch(IOException e) {
e.printStackTrace();
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}.init(socketChannel, selector)).start();
while(true) {
while(scanner.hasNextLine()) {
buf.clear();
buf.put(scanner.nextLine().getBytes());
buf.flip();
socketChannel.write(buf);
buf.flip();
}
}
} catch(IOException e) {
e.printStackTrace();
}
}
}
I have done the mistake setting this flag
key.interestOps(SelectionKey.OP_READ);
)
instead of below.
use this
socketChannel.register(this.selector, SelectionKey.OP_WRITE|SelectionKey.OP_READ);

Server Client Exception

I have a problem in running server-client program. When i run my server program , it keeps on running and never ends up. On other side, when i run my client program it throws an exception as shown below (my firewall is off).
The replies will be more than appreciated. Thanks
//Client Code
import java.io.*;
import java.net.*;
public class DailyAdviceClient
{
public void go()
{
try {
Socket s = new Socket("127.0.0.1", 4242);
InputStreamReader read = new InputStreamReader(s.getInputStream());
BufferedReader z = new BufferedReader(read);
String advice = z.readLine();
System.out.println("today you should" + advice);
z.close();
}
catch (IOException ex)
{
ex.printStackTrace();
}
}
public static void main(String[] args)
{
DailyAdviceClient x = new DailyAdviceClient();
x.go();
}
}
//Server Code
import java.io.*;
import java.net.*;
public class DailyAdvisor
{
String[] advicelist = { "take your time", "be patient",
"don't be diplomatic", " life is really short", "try to fix things" };
public void go()
{
try
{
ServerSocket s = new ServerSocket(4242);
while (true)
{
Socket m = s.accept();
PrintWriter writer = new PrintWriter(m.getOutputStream());
String advice = getAdvice();
writer.println(advice);
writer.close();
writer.flush();
System.out.println(advice);
}
} catch (IOException ex)
{
ex.printStackTrace();
}
}
private String getAdvice()
{
int random = (int) (Math.random() * advicelist.length);
return advicelist[random];
}
public static void main(String[] args)
{
DailyAdvisor x = new DailyAdvisor();
x.go();
}
}
The Server never ends up because you used a while(true) loop. It is necessary for your server to keep listening to new client connections through the accept() method.
About the exception, your code runs fine both locally and using a remote machine. Thus a network configuration error could be the cause and you must check if both server/client could see each other using the ping command. If this is the case, then check if the server is listening to the client using netstat.

Stuck with Multi-Client Chat Application

I'm trying to make a MultiClient Chat Application in which the chat is implemented in the client window. I've tried server and client code for the same. I've got two problems:
A. I believe the code should work but, server to client connections are just fine but information isn't transferred between clients.
B. I need a way to implement private one-to-one chat in case of more than two clients, I've used a class to store the information of the Socket object returned for each connection being established, but I can't figure out how to implement it.
The server code is:
import java.io.*;
import java.net.*;
class ClientInfo {
Socket socket;
String name;
public ClientInfo(Socket socket, String name) {
this.socket = socket;
this.name = name;
}
}
public class server {
private ObjectInputStream input[] = null;
private ObjectOutputStream output[] = null;
private String value = null;
private static ServerSocket server;
private Socket connection = null;
private static int i = -1;
public static void main(String args[]) {
try {
server = new ServerSocket(1500, 100);
while (true) {
System.out.println("Waiting for connection from client");
Socket connection = server.accept();
i++;
System.out.println("Connection received from " + (i + 1) + " source(s)");
//System.out.println(i);
new ClientInfo(connection, "Client no:" + (i + 1));
innerChat inc = new server().new innerChat(connection);
}
} catch (Exception e) {
System.out.println("Error in public static void main! >>>" + e);
}
}// end of main!!!
class innerChat implements Runnable {
private Socket connection = null;
public innerChat(Socket connection) {
this.connection = connection;
Thread t;
t = new Thread(this);
t.start();
}
public void run() {
try {
output[i] = new ObjectOutputStream(connection.getOutputStream());
output[i].flush();
input[i] = new ObjectInputStream(connection.getInputStream());
} catch (Exception e) {
}
}
}
}
And the client code is
import java.net.*;
import java.io.*;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.*;
import java.awt.event.*;
public class ChatappClient {
private static int port = 1500;
JFrame window = new JFrame("Chat");
JButton sendBox = new JButton("Send");
JTextField inputMsg = new JTextField(35);
JTextArea outputMsg = new JTextArea(10, 35);
private ObjectInputStream input;
private ObjectOutputStream output;
public static void main(String[] args) throws Exception {
ChatappClient c = new ChatappClient();
c.window.setVisible(true);
c.window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
c.run();
}
public ChatappClient() {
inputMsg.setSize(40, 20);
sendBox.setSize(5, 10);
outputMsg.setSize(35, 50);
inputMsg.setEditable(true);
outputMsg.setEditable(false);
window.getContentPane().add(inputMsg, "South");
window.getContentPane().add(outputMsg, "East");
window.getContentPane().add(sendBox, "West");
window.pack();
sendBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
output.writeObject(inputMsg.getText());
outputMsg.append("\n" + "Client>>>" + inputMsg.getText());
output.flush();
} catch (IOException ie) {
outputMsg.append("Error encountered! " + ie);
}
inputMsg.setText("");
}
});
inputMsg.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
output.writeObject(inputMsg.getText());
outputMsg.append("\n" + "Client>>>" + inputMsg.getText());
output.flush();
} catch (IOException ie) {
outputMsg.append("Error encountered! " + ie);
}
inputMsg.setText("");
}
});
}
private void run() throws IOException {
Socket clientSocket = new Socket("127.0.0.1", port);
output = new ObjectOutputStream(clientSocket.getOutputStream());
output.flush();
input = new ObjectInputStream(clientSocket.getInputStream());
outputMsg.append("I/O Success");
String value = null;
while (true) {
try {
value = (String) input.readObject();
} catch (Exception e) {
}
outputMsg.append(value + "\n");
}
}
}
Your code looks like it could be improved quite a bit. Your main method for instance should have none of that code in it. It should start your Server class, and that's it (and note that class names should begin with an upper case letter as per Java standards which I strongly advise you to follow).
I'm trying to make a MultiClient Chat Application in which a Server does nothing but listen and create connections.
The Server is going to have to do more than that. It will need to create Clients, it will need to maintain a collection such as an ArrayList of Clients such as an ArrayList<ChatappClient> Otherwise how do you expect the Server to connect two Clients together?
I think that in all you're going to need to think the structure and connections of this program out in more depth before starting to write code.

Categories

Resources