Why does server not respond in this programme? Client Server Java - java

I'm watching a client server java tutorial and in there tutor is developing a chat application. On the package there are two folders. In one folder , there are login ui (code), client connection and main class. In the other folder there are Server connection , Server Client connection (In this class includes to identify client in an unique way, tutor uses random generating number for one client) and main class.
When I'm running the application UI displays, But in console server and client outputs are not showing. Here is my Client code.
public class Client extends javax.swing.JFrame {
private String name,address;
private int port;
private DatagramSocket socket;
private InetAddress ip;
private Thread send;
public Client()
{
}
public Client(String name,String address, int port) {
this.name=name;
this.address=address;
this.port=port;
initComponents();
boolean connect = openConnection(address);
if(!connect){
System.err.println("Connection failed!");
console("Connection failed!");
}
console("Attempting to connection to"+ address+":"+port+",user:"+name);
String connection = "/c/"+name;
send(connection.getBytes());
}
private boolean openConnection(String address){
try{
socket =new DatagramSocket();
ip = InetAddress.getByName(address);
}catch(UnknownHostException e){
e.printStackTrace();
return false;
}catch(SocketException e){
e.printStackTrace();
return false;
}
return true;
}
//receive packets part //
private String receive(){
byte[]data=new byte[1024];
DatagramPacket packet = new DatagramPacket(data,data.length);
try{
socket.receive(packet);
}catch(IOException e){
e.printStackTrace();
}
String message =new String(packet.getData());
return message;
}
//send data
private void send(final byte[] data){
send = new Thread("send"){
public void run(){
DatagramPacket packet = new DatagramPacket (data,data.length,ip,port);
try{
socket.send(packet);
}catch(IOException e){
e.printStackTrace();
}
}
};
send.start();
}
private void send(String message){
if(message.equals(""))
return;
message= name+":"+message;
console(message);
send(message.getBytes());
txtMessage.setText("");
}
Server class (This includes in a sperate folder)
public class Server implements Runnable {
private List<ServerClient> clients = new ArrayList<ServerClient>();
private DatagramSocket socket;
private int port;
private boolean running = false;
private Thread run, manage, send, receive;
public Server(int port) {
this.port = port;
try {
socket = new DatagramSocket(port);
} catch (SocketException e) {
e.printStackTrace();
return;
}
run = new Thread(this, "Server");
run.start();
}
public void run() {
running = true;
System.out.println("Server started on port " + port);
manageClients();
receive();
}
private void manageClients() {
manage = new Thread("Manage") {
public void run() {
while (running) {
// Managing
}
}
};
manage.start();
}
private void receive() {
receive = new Thread("Receive") {
public void run() {
while (running) {
byte[] data = new byte[1024];
DatagramPacket packet = new DatagramPacket(data, data.length);
try {
socket.receive(packet);
} catch (IOException e) {
e.printStackTrace();
}
String string = new String(packet.getData());
System.out.println(string);
}
}
};
receive.start();
}
private void process(DatagramPacket packet){
String string = new String(packet.getData());
if(string.startsWith("/c/")){
UUID id= UUID.randomUUID();
System.out.println(id.toString());
clients.add(new ServerClient(string.substring(3,string.length()),packet.getAddress(),packet.getPort(),50));
System.out.println(string.substring(3,string.length()));
}else{
System.out.println(string);
}
}
In tutorial ,tutor runs this server code without main method. But It doesn't run in netbeans.
In Server class package main method
public class ServerMain {
private int port;
private Server server;
public ServerMain(int port){
this.port=port;
server = new Server(port);
}
public static void main(String[] args){
int port;
if(args.length!=1){
System.out.println("Usage: java-jar MyChat.jar[port]");
return;
}
port=Integer.parseInt(args[0]);
new ServerMain(port);
}
In client chat package main method.
public class YakaaChat {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
}
}

Related

Why is DatagramPacket object get stuck when using one of it's methods? [duplicate]

This question already has an answer here:
Can not access object's properties(methods) from within the run method! Java Multithreading
(1 answer)
Closed 5 years ago.
I am using a server and a client to share information via UDP packets.
The client assembles a packet and sends it to the server.
The server receives the packet , and issues a thread to handle it.
In the threads code I try to use the packet but I get stuck for every method I use: getAddress() , getData() , etc.
When I try to use the packet's methods in the Server's code - it doesn't get stuck. Only in the Threads'.
I don't understand why I get stuck when using the packet in the thread's code
Here is the code and it compiles:
The Client
public class ExchangeClientProgram
{
public final double ERROR = 0;
private DatagramPacket packet;
private DatagramSocket socket;
private InetAddress hostAddress;
private int port;
private byte [] buf;
public ExchangeClientProgram(String hostIp , int port) throws SocketException, UnknownHostException
{
this.port = port;
socket = new DatagramSocket();
hostAddress = InetAddress.getByName(hostIp);
}
public boolean sendRequestPacket(ExchangeRequest exchangeRequest)
{
try
{
buf = ExchangeServerProgram.convertObjectToByteArr(exchangeRequest);
if(null != buf)
{
packet = new DatagramPacket(buf, buf.length, hostAddress , port);
socket.send(packet);
return true;
}
else
JOptionPane.showMessageDialog(null, "Sorry, this exchange cannot be trasnmitted to server");
} catch (IOException e){e.printStackTrace();}
return false;
}
}
The Server
public class ExchangeServerProgram extends Thread
{
public static final int DEFAULT_SERVER_PORT = 4444;
public static final int DEFAULT_BUFFER_SIZE = 1024;
private DatagramSocket socket;
private DatagramPacket packet;
private boolean listening = false;// default initial value
private byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
public ExchangeServerProgram() throws SocketException
{
socket = new DatagramSocket(DEFAULT_SERVER_PORT);
packet = new DatagramPacket(buffer , buffer.length);
}
public void run()
{
listening = true;
while(listening)
{
try
{
socket.receive(packet);
packet.getAddress(); // this line BEFORE the thread starts works fine.
new ExchangeClientRequestHandlerThread(packet ).start(); // inside this thread the trouble starts
// when using the SAME line from above
} catch (IOException e){e.printStackTrace();}
}
}
public static byte [] convertObjectToByteArr(Object obj)
{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte [] buffer = null;
ObjectOutput out = null;
try {
out = new ObjectOutputStream(bos);
out.writeObject(obj);
out.flush();
buffer = bos.toByteArray();
}
catch (IOException e){e.printStackTrace(); }
finally {
try
{
bos.close();
} catch (IOException e){e.printStackTrace(); }
}
return buffer;
}
}
The Thread Handling The Packet, here is where I get stuck
public class ExchangeClientRequestHandlerThread extends Thread
{
private DatagramPacket packet;
public ExchangeClientRequestHandlerThread(DatagramPacket packet)
{
this.packet = packet;
}
public void run()
{
if(null == packet)
return;
packet.getAddress(); //... get stuck here
System.out.println("doesn't get to this code line");
}
}
ExchangeRequest
public class ExchangeRequest implements Serializable
{
private static final long serialVersionUID = -1355753051547829379L;
private String coinFrom;
private String coinTo;
private double amount;
private int requestId;
public ExchangeRequest(String coinFrom, String coinTo, double amount , int requestId)
{
this.coinFrom = coinFrom;
this.coinTo = coinTo;
this.amount = amount;
this.requestId = requestId;
}
//getters & setters
}
Main
public class Main
{
public static void main(String [] args)
{
try
{
ExchangeServerProgram server = new ExchangeServerProgram();
server.start(); // starts the server
String inputIpAddress = "localhost";
ExchangeClientProgram clientProgram = new ExchangeClientProgram(inputIpAddress, ExchangeServerProgram.DEFAULT_SERVER_PORT);
ExchangeRequest request = new ExchangeRequest("usd", "euro", 4, 1111); // 1111 is just an ID number for the message
clientProgram.sendRequestPacket(request);
while(true)
{
// this while loop is just for the example
// here I am waiting for received packet
// via "socket.receive();"
}
} catch (SocketException | UnknownHostException e)
{
e.printStackTrace();
}
}
}
Threading is your problem. You have one thread calling receive(packet), and when you receive it you pass it to another thread for processing, making the first thread call receive(packet) again.
The problem is that receive synchronizes on packet and methods in DatagramPacket are synchronized, so while the first thread is blocked on receive(packet) you can't call any of the DatagramPacket methods without it blocking the thread.
Possible solutions include processing the packet in the original thread or creating a new DatagramPacket for each receive().

Java "NotSerializableException: java.net.Socket" When Not Sending A Socket

So I send a Server object to a client with this thread:
public ConnectionThread(final Server server) {
super(new Runnable() {
public void run() {
try {
Socket client = server.serverSocket.accept();
server.clients.add(client);
ObjectInputStream in = new ObjectInputStream(
client.getInputStream());
ObjectOutputStream out = new ObjectOutputStream(
client.getOutputStream());
System.out.println("Connected client: "
+ client.getRemoteSocketAddress());
server.launchNewThread();
Object input;
while (!client.isClosed()) {
input = in.readObject();
if (input != null) {
if (input.toString().equals("server")) {
out.writeObject(server);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
And when I call out.writeObject(server) I get this exception:
java.io.NotSerializableException: java.net.Socket
Here is the Server class:
public class Server implements Serializable {
private static final long serialVersionUID = 4634111951586948020L;
public ServerArgs args;
public ArrayList<Socket> clients = new ArrayList<Socket>();
public ServerSocket serverSocket;
public Server(int port) throws IOException {
serverSocket = new ServerSocket(port);
launchNewThread();
}
public void launchNewThread() {
ConnectionThread thread = new ConnectionThread(this);
thread.start();
}
public static void main(String[] args) throws IOException {
new Server(27015);
}
}
public ArrayList<Socket> clients = new ArrayList<Socket>();
public ServerSocket serverSocket;
You have plenty of non-serializable sockets right there. It's very unclear what the purpose of "sending a server" is, but perhaps you should either just send the ServerArgs or mark those two fields transient.

Android TCP socket: How to set a listener for incomming/received data

I'm developing a android client which communicates with a server using TCP protocol. everything is okay except for receiving data from the server. the only way i know for now, is to periodically check if there is something to read, an that's bad. is there any listener, callback or any way to get informed when the client receives a message so that i can run a method to read and process it ?
Here is my code
class QTcpSocket implements Runnable {
private String ip="";
private int port;
private Socket socket;
private DataOutputStream dataOutputStream;
private DataInputStream dataInputStream;
public QTcpSocket(String ip, int port) {
this.ip = ip;
this.port = port;
}
public void setIp(String ip) {
this.ip = ip;
}
public String getIp() {
return this.ip;
}
public void setPort(int port) {
this.port = port;
}
public void run() {
try {
socket = new Socket(this.ip, this.port);
dataOutputStream = new DataOutputStream( socket.getOutputStream() );
dataInputStream = new DataInputStream(socket.getInputStream());
String response = dataInputStream.readUTF();
} catch (IOException e) {
e.printStackTrace();
}
}
public void sendMessage(String message) {
try {
byte[] buffer= message.getBytes();
dataOutputStream.write(buffer,0,buffer.length);
}catch (IOException e) {
e.printStackTrace();
}
}
public void disconnect() {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public boolean isClosed() {
return socket.isClosed();
}
}

Connection Refused - Java Client/Server

I'm trying to create a java push server model for testing on my own machine, this won't be used to connect external clients as the server and client will be on the same machine. After the client connects on the port specified by he/she, they should send a message of their choice that will be sent back to them, and any other clients connected to the same port.
The problem I'm having is i receive a java.net.ConnectException: Connection refused: connect when this is attempted. Below is the client and the server.
Edit: I've taken the time to ensure that the necessary ports are open too, and even disabled my firewall, but to no avail.
Server:
class MainServer {
// port that oir server is going to operate on
final static int port = 1234;
public static void main(String[] args) {
// this is going to model the server for the moment
System.out.println("Server has been started...");
Buffer<Messages> store = new Buffer<Messages>(10);
new Writer(store).start();
try {
ServerSocket serve = new ServerSocket(port);
while(true) {
// wait for server request
Socket socket = serve.accept();
// start thread to service request
new ServerThread(socket,store).start();
}
} catch(IOException e) {e.printStackTrace();}
}
}
class ServerThread extends Thread {
Socket socket;
Buffer<Messages> buffer;
public ServerThread(Socket s, Buffer<Messages> b) {
socket = s;buffer = b;
}
public void run() {
try {
DataInputStream in = new DataInputStream(socket.getInputStream());
int port = in.readInt();
System.out.println("Port: "+port);
Messages ms = new Messages(port);
// Read message as string from user
String message = in.readUTF();
int k = in.readInt();
while(k != -1) {
// Add message to array
// read next message
ms.add(message);
message = in.readUTF();
}
// close connection
socket.close();
// add message to buffer
buffer.put(ms);
} catch(IOException e) {e.printStackTrace();}
}
}
class Writer extends Thread {
Buffer<Messages> buffer;
public Writer(Buffer<Messages> m) {buffer = m;}
public void run() {
while(true) {
Messages dp = buffer.get();
dp.write();
}
}
}
class Buffer <E> {
/**
* Producer & Consumer Buffer
*/
private int max;
private int size = 0;
private ArrayList<E> buffer;
private Semaphore empty; //control consumer
private Semaphore full; // control producer
private Lock lock = new ReentrantLock();
public Buffer(int s) {
buffer = new ArrayList<E>();
max = s;
empty = new Semaphore(0);
full = new Semaphore(max);
}
// add data to our array
public void put(E x) {
try {
full.acquire();
} catch(InterruptedException e) {}
// sync update to buffer
lock.lock();
try {
buffer.add(x);
size++;
empty.release();
} finally {lock.unlock();}
}
public E get() {
try {
empty.acquire();
} catch(InterruptedException e) {}
// sync uodate on buffer
lock.lock();
try {
E temp = buffer.get(0);
buffer.remove(0);
size--;
full.release();
return temp;
} finally {lock.unlock();}
}
}
final class Messages {
private final int port;
private final ArrayList<String> data = new ArrayList<String>();
public Messages(int p) {port = p;}
void add(String message) {
data.add(message);
}
void write() {
try {
Socket socket;
socket = new Socket(InetAddress.getLocalHost(),port);
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
// write message
out.write(data.size());
for(String k : data) {out.writeUTF(k);}
out.flush();
socket.close();
} catch(IOException e) {e.printStackTrace();}
}
}
Client:
class Client {
final static int nPort = 1234;
static int serverPort;
public static void main(String[] args) {
// this class and those present in it
// will model the client for assignment 8
Scanner in = new Scanner(System.in);
System.out.println("Please enter the messageboard number: ");
serverPort = in.nextInt();
System.out.println("Please type your message: ");
String msg = in.next();
Listener lis = new Listener(serverPort);
lis.start();
boolean go = true;
while(go) {
try {
Thread.sleep(2000);
} catch(InterruptedException e) {}
write(serverPort, msg);
System.out.println("Continue: 0/1");
int x = in.nextInt();
if(x == 0)go = false;
}
System.exit(0);
}
static void write(int port, String msg) {
try {
Socket socket;
socket = new Socket(InetAddress.getLocalHost(),port);
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
// send message to port
out.writeInt(port);
out.writeUTF(msg);
// write sentinal after message has been written and close socket
out.writeInt(-1);
out.flush();
socket.close();
} catch(IOException e) {System.out.println(e);}
}
}
class Listener extends Thread {
private int port;
volatile boolean go;
public Listener(int p) {p = port;}
public void run() {
try {
ServerSocket serversock = new ServerSocket(port);
while(go) {
Socket socket = serversock.accept();
DataInputStream in = new DataInputStream(socket.getInputStream());
// Read the message
while(in.available() > 0) {
String k = in.readUTF();
System.out.print(k+" ");
}
System.out.println();
socket.close();
}
} catch(IOException e) {go = false;}
}
}
Turns out i had a wrong assignment in my Listener class. I had p = port instead of port = p.
Solved. Through my own stupidity.
The hostname you are connecting to is localhost so you are assuming the server is on the same machine. If you need to connect to a different machine, you need to specify the host you want it to connect to.
Try changing socket = new Socket(InetAddress.getLocalHost(),port);
to
socket = new Socket(*IP OF SERVER (127.0.0.1 if same machine)*, port);

Java server client networking

Should I open - close the connection each time my client GUI sends a message or open a connection one time and keep it open ?
Im sending data using BufferedWriter but this methid just seems to work for one time only, after doing the write and the flush method Im able just to send 1 message to my server, then it just doesnt get the data im sending...
Client connects - sends data to server (1st time) - Works
Client sends data again - no data echoed on server console.
Should I open a bufferedwriter each time I want to send data or keep one open all the time and never close it?
My actual code - Client side
Main
public class Main {
public static void main(String args[]) {
Client chat = new Client("localhost", 6111);
}
}
Client
public class Client {
public Client(String host, int port) {
SwingUtilities.invokeLater(new Runnable() {
private Socket chat;
public void run() {
try {
this.chat = new Socket("localhost", 6113);
} catch ( IOException e) {
e.printStackTrace();
}
Gui gui = new Gui("Chat", this.chat);
}
});
}
}
GUI
public class Gui {
private JFrame frame;
private JTextArea area;
private JTextField field;
private JMenuBar menu;
private JButton button;
private Socket socket;
private BufferedWriter write;
public Gui(String title, Socket socket) {
this.socket = socket;
try {
this.write = new BufferedWriter(new OutputStreamWriter(this.socket.getOutputStream()));
} catch (IOException e) {
e.printStackTrace();
}
this.frame = new JFrame(title);
this.frame.setSize(new Dimension(400, 400));
this.frame.setLayout(new BorderLayout());
this.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.frame.setResizable(false);
Elements interfce = new Elements(this.frame);
this.field = interfce.addField("Texto to send...");
this.menu = interfce.addBar();
this.area = interfce.addArea();
this.button = interfce.addButton("Send");
this.button.addActionListener(new Listener(this.field, this.socket, this.write));
this.menu.add(this.field);
this.menu.add(this.button);
this.frame.setVisible(true);
}
}
Listener (sends data)
public class Listener implements ActionListener {
private JTextField text;
private Socket chat;
private BufferedWriter writer;
public Listener(JTextField field, Socket chat, BufferedWriter write) {
this.text = field;
this.chat = chat;
this.writer = write;
}
public void actionPerformed(ActionEvent e) {
System.out.println(this.text.getText());
try {
writer.write("Hello\n");
writer.flush();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
And the server
public class Main {
public static void main(String args[]) {
Server chat = new Server(6113);
}
}
public class Server {
private int port;
private ServerSocket server;
public Server(int port) {
this.port = port;
startServer();
}
public void startServer() {
try {
this.server = new ServerSocket(this.port);
System.out.println("Starting chat server at port " + this.port + "...");
while (true) {
Socket s = this.server.accept();
System.out.println("Client connected - " + s.getLocalAddress().getHostName());
Thread client = new Thread(new Client(s));
client.start();
}
} catch (IOException e) {
System.out.println("Error found!");
e.printStackTrace();
}
}
}
public class Client implements Runnable {
private Socket client;
public Client(Socket client) {
this.client = client;
}
public void run() {
try {
BufferedReader read = new BufferedReader(new InputStreamReader(this.client.getInputStream()));
System.out.println("Client says - " + read.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
}
Should I open - close the connection each time my client GUI sends a message or open a connection one time and keep it open ?
Connection between a Client and Server is generally open for the entire session of messaging and not recreated for sending each message. So keep it open until the client or the Server has to go away.
Look at your Client thread that you start in your server upon accepting a Connection.
public void run() {
try {
BufferedReader read = new BufferedReader(new InputStreamReader(this.client.getInputStream()));
System.out.println("Client says - " + read.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
Does this give you a hint ? Well - you have to arrange for some sort of looping here within your run() - listening for more inputs from that client.
Just do some changes
Server side:
public void run() {
try {
BufferedReader read = new BufferedReader(new InputStreamReader(
this.client.getInputStream()));
while (true) {
System.out.println("Client says - " + read.readLine());
}
} catch (IOException e) {
e.printStackTrace();
}
}
Client side:
use PrintWriter instead of BufferedWriter that provide print new line functionality and auto flush property.
this.write = new PrintWriter(new OutputStreamWriter(this.socket.getOutputStream()),
true);
....
public void actionPerformed(ActionEvent e) {
System.out.println(this.text.getText());
try {
writer.write(this.text.getText());
writer.println();
} catch (Exception e1) {
e1.printStackTrace();
}
}

Categories

Resources