i was trying creating Client/server Chat in console "not gui" , in gui case i can add action listener to the JTextField and every time that user hit enter the data will be send it to the client and vise versa , in console java application how can i do that ?? i mean how could i listen to the console (or) should i listen to the BufferReader so if it full then read the Buffer ???
You can do smth like :
String StrRead() {
byte[] enter = new byte[256];
int num = 0;
String str = new String();
try {
num = System.in.read(enter);
}
catch (Exception e)
{
System.out.println(e.toString());
}
str = new String(enter,0,num);
return str.trim();
}
and then just call String s = StrRead();
Related
I am trying to make client-server connection. First I have executed server code in one console and then client code in another console. I want that after the client code runs, the client enters his name and then I will create the object of client socket class and print the name of client in the server console. But on the server console it prints null when I try to print the name of client.
Since accept() method of server class waits for the client socket object, so before this line System.out.println(Myclient1.nameOfClient + " connected"); gets executed, client would already have entered his name in String nameOfClient.
I am unable to understand the reason behind this.
Server code
public Myserver1() {
try {
ss = new ServerSocket(10);
while (true) {
s = ss.accept(); // waits for the client socket
System.out.println(Myclient1.nameOfClient + " connected"); // Here I want to print the name of client(Myclient1.java).
al.add(s);
Runnable r = new MyThread(s, al);
Thread t = new Thread(r);
t.start();
}
} catch(Exception e) {}
}
Client code
public Myclient1() {
System.out.println("enter ur name");
nameOfClient = new Scanner(System.in).nextLine(); // Here I am storing the name of client so that I can access nameOfClient from Myserver1.java
try {
s = new Socket("localhost", 10);
din = new DataInputStream(s.getInputStream());
dout = new DataOutputStream(s.getOutputStream());
clientchat();
} catch(Exception e) {}
}
Server and clients should run independently of each other, or else it defeats the purpose of networking.
Right now, you are accessing a static variable the has never been initalized because the client isnt running in the same process as the server.Send the name over a socket, and use that as your print and your problem will be fixed.
I have a Server-Client program where I get clients IP address when they connect to my server system using this line of code:
//connecting to clients
void connect_clients()
{
try {
ServerSocket listener = new ServerSocket(7700);
jButton2.setText("Server Running!");
jButton2.setEnabled(false);
try {
while (true) {
Socket socket = listener.accept();
try {
System.out.println("Client conneted from :" + socket.getLocalAddress().getHostName();
}
finally {
socket.close();
}
}
}
finally {
listener.close();
}
}
catch (IOException ex) {
Logger.getLogger(Test_Frame.class.getName()).log(Level.SEVERE, null, ex);
}
}
Now I need to assign it to a JButton, so that the Button is clicked, a small message goes to that client (From that IP Address).
How can I achieve this?
Based on what you are showing us, I cannot see the implementation or code for the Button in question (i.e. The button that will be sending the message to the IP.)
However what I can tell you is how you can accomplish that. Simply assign the IP address before printing it out. Then from within your Buttons Action method, you can use the variable.
For instance:
UPDATED
The only option I see to this is to create a variable that will track how many clients are connected and name the buttons according to this. Also just for testing purposes, name the button the Host name so you know which button is relevant to which button. See below:
Create a Global Variable called "clientIP", as well as an Integer to tract the number of clients, as well as an ArrayList to store the client buttons required.
//note that .getHostName returns a String represenation of the hostname from that IP
String clientIP = "";
int clientNumber = 0;
ArrayList<JButton> buttons = new ArrayList<JButton>();
Next assign the hostname when it is fetched within the try/catch:
try{
clientIP = socket.getLocalAddress().getHostName();
//This will add a new Button to the ArrayList with the Text of the Button being the Clients Host Name
buttons.add(new JButton(clientIP));
System.out.println("Client conneted from :" + clientIP);
displayButton(buttons.get(clientNumber);
clientNumber++;
}
In terms of implementation of Actions you can then do the following:
public void actionPerformed( ActionEvent e ){
if ( e.getSource() == buttons.get(0) )
//this line to assign the hostname to a variable so that we can use it to send the message
String thisIP = buttons.get(0).getText();
//now use this to send your message
if ( e.getSource() == buttons.get(1) )
String thisIP = buttons.get(1).getText();
//now use this to send your message
if ( e.getSource() == buttons.get(2) )
String thisIP = buttons.get(2).getText();
//now use this to send your message
if ( e.getSource() == buttons.get(3) )
String thisIP = buttons.get(3).getText();
//now use this to send your message
}
In order to display the buttons, you can simply have a method created that will print out the Button at that position everytime it is created (From with your Try statement)
public static void displayButton(JButton newButton){
// this line is to display the button on your JFrame. Edit the "frame" according to what the name of your JFrame is.
frame.add(newButton);
}
Hope this answers your question!
Let me know of the outcome.
I searched the internet and i didn't find something for my question.
I have my client class, my server class and a Loc class. In my client class, i have a Jtext field, that i want to populate with values (free/occupied) depending if the seat is free or not.
In my server class i populate an ArrayList with all the seats free. I want to pass this ArrayList to my client and in the same time to display something like FREE FREE OCCUPIED.
But i can only pass my first value.
Here is the server class:
public static void main(String [] args){
ServerSocket client = null;
Loc l = new Loc();
try {
ArrayList<Loc> lista = new ArrayList<>();
for (int i=0;i<7;i++)
for(int j=0;j<6;j++)
{
l.setLoc(i);
l.setRand(j);
lista.add(l);
}
client = new ServerSocket(9000);
Socket socket = client.accept();
ObjectInputStream dis = new ObjectInputStream(socket.getInputStream());
ObjectOutputStream dos = new ObjectOutputStream(socket.getOutputStream());
l = (Loc) dis.readObject();
System.out.println(l.getRand());
// Loc a = new Loc("ags",2, 42, 125);
dos.writeObject(lista);
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
} catch (ClassNotFoundException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
And here is my client class:
public class Client_Gui extends javax.swing.JFrame {
Socket socket = null;
ObjectOutputStream dos = null;
ObjectInputStream dis= null;
// ObjectOutputStream dos = null;
ArrayList<Loc> lst = new ArrayList<>();
Loc locul = new Loc();
/**
* Creates new form Client_Gui
*/
public Client_Gui() {
initComponents();
Loc loc = new Loc();
try {
ArrayList<Loc> lst = null;
socket = new Socket("localhost",9000);
dos = new ObjectOutputStream(socket.getOutputStream());
dis = new ObjectInputStream(socket.getInputStream());
dos.writeObject(loc);
lst = (ArrayList<Loc>) dis.readObject();
for(Loc a : lst){
if(a.getIdSpectator().equals("") == true)
txt_area.setText("Liber");
else
txt_area.setText("Ocupat");
}
} catch (IOException ex) {
Logger.getLogger(Client_Gui.class.getName()).log(Level.SEVERE, null, ex);
} catch (ClassNotFoundException ex) {
Logger.getLogger(Client_Gui.class.getName()).log(Level.SEVERE, null, ex);
}
}
And another question related to this. Can i run my client/server application without sending first some information from the client? I mean, at first i tried to read from client first and then write to server but i got errors. After i changed, and first i write from client and then read, works normally, until it reaches that part with ArrayList.
EDIT: i tried to hard code and in my Client class i put the array list created by code.
Now, when i want to show it in the text field, still only the first value is displayed. Is my syntax wrong?
i used:
for(Loc a : lista){
if(a.getIdSpectator().equals("") == true)
txt_area.setText("Liber");
else
txt_area.setText("Ocupat ");
}
EDIT2: Jasper was right. I used append and now it works. Thanks.
Take a look at how you are constructing the list on the server....
ArrayList<Loc> lista = new ArrayList<>();
for (int i=0;i<7;i++)
for(int j=0;j<6;j++)
{
l.setLoc(i);
l.setRand(j);
lista.add(l);
}
Basically, all this is doing is adding the same instance of l to the array list, but on each loop, you are changing its properties. This means, you'll end up with a list of the same object with the same properties (cause it's just the single instance of the object)
What you should be doing is on each iteration of your loop is creating a new instance of what ever l is, setting its properties according only and that to the list
Updated
Okay, on client, you're setting the text of the JTextArea using
for(Loc a : lst){
if(a.getIdSpectator().equals("") == true)
txt_area.setText("Liber");
else
txt_area.setText("Ocupat");
}
setText replaces the contents of the field with the supplied text. Instead, you want to try using append
for(Loc a : lst){
if(a.getIdSpectator().equals("") == true)
txt_area.append("Liber");
else
txt_area.append("Ocupat");
}
Having said that, I would highly recommend that you consider taking a look at How to Use Tables and How to Use Lists for components that are better suited to display this type of data
You need to put it in a loop so all of your values passed from the socket will be recieve by the server not just the first value you send.
example:
in server
ObjectOutputStream dos = new ObjectOutputStream(socket.getOutputStream());
dos.writeObject(lista);
while(true)
{
l = (Loc) dis.readObject();
System.out.println(l.getRand());
// Loc a = new Loc("ags",2, 42, 125);
}
in client
dis = new ObjectInputStream(socket.getInputStream());
lst = (ArrayList<Loc>) dis.readObject();
for(Loc a : lst){
if(a.getIdSpectator().equals("") == true)
txt_area.setText("Liber");
else
txt_area.setText("Ocupat");
}
your question:
Can i run my client/server application without sending first some information from the client?
just always remember when you are trying to read data packet, someone should write data first.
There's a simple console application that consists of server side and client side. Server side listens to some port, when client connects server starts to send questions in menu-like style. For example:
Print exist data
Add new data
Edit exist data
Remove exist data
Client in its turn sends menu number and waits for server's reaction. After each command server must send menu list again.
As you will see from example below, Client connects to the Server and reads its menu, then starts to interact with it. But this interaction isn't as smooth as it expected. Sometimes data is sent by pieces. Each client response should be followed by Enter pressed twice in order to get response from Server.
Here is ready to compile example of the problem I ran at in my app:
Server (one Java project):
public class TestServer {
private static List<String> example;
static {
example = new ArrayList<String>();
for(int i = 0; i < 5; ++i) {
example.add("Data#" + i);
}
}
private static DataInputStream in;
private static DataOutputStream out;
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(30000);
System.out.println("*** Waiting for a client...");
Socket socket = serverSocket.accept();
System.out.println("*** Client connected!\n");
in = new DataInputStream(socket.getInputStream());
out = new DataOutputStream(socket.getOutputStream());
while (true) {
showUserMenu();
String clientMessage = in.readUTF();
System.out.println("Client made a choice: " + clientMessage);
try {
int answerChoice = Integer.parseInt(clientMessage);
analyzeSelection(answerChoice);
System.out.println("Waiting for client menu choice...\n");
} catch (NumberFormatException e) {
System.out.println(e.getMessage());
}
}
}
private static void analyzeSelection(int answerChoice) {
try {
switch(answerChoice) {
case 1:
printExistData();
break;
case 2:
//2. Add data
createNewData();
out.writeUTF("New data added!");
out.flush();
break;
default:
out.writeUTF("There is no such menu item. Please enter correct menu number");
out.flush();
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
private static void createNewData() throws IOException {
StringBuilder builder = new StringBuilder();
out.writeUTF("Do you want to set change name? (y/n)");
out.flush();
if(isYes()) {
out.writeUTF("Enter data name: ");
out.flush();
builder.append(in.readUTF());
}
out.writeUTF("Do you want to set data value? (y/n)");
if(isYes()) {
out.writeUTF("Enter data value: ");
out.flush();
builder.append(in.readUTF());
}
example.add(builder.toString());
}
private static boolean isYes() throws IOException {
return in.readUTF().toLowerCase().equals("y");
}
private static void printExistData() throws IOException {
StringBuilder builder = new StringBuilder();
for(String s : example) {
builder.append("- ").append(s).append("\n");
}
out.writeUTF(builder.toString());
out.flush();
}
private static void showUserMenu() throws IOException {
StringBuilder builder = new StringBuilder();
builder.append("1. Print exist data\n").append("2. Add new data\n")
.append("*** Type menu number and press Enter.");
out.writeUTF(builder.toString());
out.flush();
}
}
Client (another Java project):
public class TestClient {
public static void main(String[] args) throws IOException {
InetAddress ipAddress = InetAddress.getByName("127.0.0.1");
System.out.println("*** Ready to connect to 127.0.0.1:30000");
Socket socket = new Socket(ipAddress, 30000);
System.out.println("*** Connection established!");
DataInputStream in = new DataInputStream(socket.getInputStream());
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
//Read client input from keyboard
BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in));
while(true) {
String serverResponse = in.readUTF();
System.out.println(serverResponse);
String clientResponse = keyboard.readLine();
out.writeUTF(clientResponse);
out.flush();
}
}
}
This is the overall output of communication between client and server:
[SERVER]*** Waiting for a client...
[CLIENT]*** Ready to connect to 127.0.0.1:30000
[CLIENT]*** Connection established!
[SERVER]*** Client connected!
[CLIENT]1. Print exist data
2. Add new data
*** Type menu number and press Enter.
[CLIENT]1
[SERVER]Client made a choice: 1
[CLIENT]- Data#0
- Data#1
- Data#2
- Data#3
- Data#4
[SERVER]Waiting for client menu choice...
[CLIENT] //Press Enter because no menu was printed
[SERVER]Client made a choice:
[SERVER]For input string: "" //NumberFormatException (NFE)
[CLIENT]1. Print exist data
2. Add new data
*** Type menu number and press Enter.
[CLIENT]2
[SERVER]Client made a choice: 2
[CLIENT]1. Print exist data
2. Add new data
*** Type menu number and press Enter.
[CLIENT]2
[CLIENT]Do you want to set change name? (y/n)
[CLIENT]y
[CLIENT]Do you want to set data value? (y/n)
[CLIENT]y
[CLIENT]Enter data value:
[SERVER]Waiting for client menu choice...
[CLIENT]123
[SERVER]Client made a choice: 123
[SERVER]Waiting for client menu choice...
[CLIENT]New data added!
[CLIENT] //Press Enter because no menu was printed
[SERVER]Client made a choice:
[SERVER]For input string: "" //NFE
...
I see that there is some sort of sync problem. But I cannot understand why it happens.
What is wrong in this communication schema? What is usual way to make client-server communication be more consistent?
Your streams should not be static, and they should not even be members of the server class. They should be non-static members of the Runnable class that you should instantiate when you create the new Thread that you should create to handle each connection.
I was just wondering how to send an int from a Java application to a C application using sockets. I have got different C programs communicating with each other and have got the Java application retrieving data from the C application, but I can't work out sending.
The C application is acting as database, the Java application then sends a user id (a 4 digit number) to the C application, if it exists it returns that record's details.
In Java I have tried using a printWriter and DataOutputStream to send the data, printWriter produces weird symbols and DataOutputStream produces "prof_agent.so".
Any help would be appreciated as I don't have a good grasp of sockets at the moment.
You can use DataOutputStream.writeInt. It writes an int already in network byte order by contract.
On a C side you can call recv, or read to fill in the 4-byte buffer, and then you can use ntohl ( Network-TO-Host-Long ) to convert the value you've just read to your platform int representation.
You can send the textual representation. So the number 123 would be sent as 3 bytes '1' '2' '3'.
It's a bit too late but let this answer be here. Using UDP sockets:
Java code:
public void runJavaSocket() {
System.out.println("Java Sockets Program has started."); int i=0;
try {
DatagramSocket socket = new DatagramSocket();
System.out.println("Sending the udp socket...");
// Send the Message "HI"
socket.send(toDatagram("HI",InetAddress.getByName("127.0.0.1"),3800));
while (true)
{
System.out.println("Sending hi " + i);
Thread.currentThread();
Thread.sleep(1000);
socket.send(toDatagram("HI " + String.valueOf(i),InetAddress.getByName("127.0.0.1"),3800));
i++;
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
public DatagramPacket toDatagram(
String s, InetAddress destIA, int destPort) {
// Deprecated in Java 1.1, but it works:
byte[] buf = new byte[s.length() + 1];
s.getBytes(0, s.length(), buf, 0);
// The correct Java 1.1 approach, but it's
// Broken (it truncates the String):
// byte[] buf = s.getBytes();
return new DatagramPacket(buf, buf.length,
destIA, destPort);
}
C# code:
string returnData;
byte[] receiveBytes;
//ConsoleKeyInfo cki = new ConsoleKeyInfo();
using (UdpClient udpClient = new UdpClient(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 3800)))
{
IPEndPoint remoteIpEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 3800);
while (true)
{
receiveBytes = udpClient.Receive(ref remoteIpEndPoint);
returnData = Encoding.ASCII.GetString(receiveBytes);
Console.WriteLine(returnData);
}
}
Try this:
Socket s = ...;
DataOutputStream out = null;
try {
out = new DataOutputStream( s.getOutputStream() );
out.writeInt( 123456 );
} catch ( IOException e ) {
// TODO Handle exception
} finally {
if ( out != null ) {
try {
out.close();
} catch ( IOException e ) {
// TODO Handle exception
}
}
}
It whould help if you could explain a little more what your problem is.