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.
Related
I am new to java server and client. I want to make a multi-client server. After making server code ready to accept more than one client it is like this :
Server code :
public class Server {
int clientNumber = 1;
ServerSocket mServer = new ServerSocket(9090);
try {
while (true) {
new TheServer(mServer.accept(), clientNumber++).start();
}
} finally {
mServer.close();
}
}
private static class TheServer extends Thread {
private Socket client;
private int clientNumber;
public TheServer(Socket client, int clientNumber) {
this.client = client;
this.clientNumber = clientNumber;
}
public void run() {
try {
DataOutputStream dos = new DataOutputStream(client.getOutputStream());
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in));
dos.writeUTF(numberString);
while (true) {
String message = br.readLine();
dos.writeUTF(message);
}
} catch (IOException e) { }
}
}
The clients are added to the server as I expect.
If I have one client, the --- dos.writeUTF(message); --- give the desired result inside client console, so in server console I write down (A) and press enter, then the (A) is printed inside #1 Client, then I write down (B) in server console and press enter, then the (B) is printed inside #1 Client, it seems good.
But if the second client join the server, the result inside both clients console is hold for one time press and is fired on second enter press. To simplify : Inside server console I press (A) and press enter, nothing is happening on clients consoles, then I press (B) inside server console again, and now the first message (A) and second message (B) are printed one (A) inside #1 Client and one (B) inside #2 Client and this is not the behavior that I expect.
What I expect: When 2 Clients exist and server send message (A), I need all Clients (here there are 2 clients) get the message together. Imagine you are playing a game online, If I have a character (like a ball) and I move it inside a game field, all the other players have to see my character moving. I wish I was clear.
I think I have to make an array to keep the clients and send message to that array maybe...
So how can I solve it. If the client code is needed please tell me.
Look into something called the Publish-Subscribe pattern, also known as the Observer pattern, here is an example:
https://www.journaldev.com/1739/observer-design-pattern-in-java
So I am working on a poker game that is using a peer-to-peer network architecture for a school project. Right now I am currently working on the whole multiplayer element of the game and I am designing my peers to be connecting a ring style format such as what is seen below
So for my algorithm, when a user executes the program they give a port number and a ServerSocket is created. The ServerSocket will listen for new players to join, and then if and only if the member variable nextPeer is null then we will assign nextPeer to this socket and continue listening. If the variable nextPeer is not null, then the client will take the information of the socket trying to join and send that information to the nextPeer variable until a client with a null nextpeer variable is found and the peer tying to join will be connected to the client with a null nextPeer variable found. The code for the creating a new game is found below.
public void createNewGame(int credits) throws IOException
{
this.player = new Player(1, credits);
this.routingTable = new ArrayList<Socket>();
(new Thread(this)).run();
String s = "";
Scanner in = new Scanner(System.in);
System.out.println("Please input a s or S to begin game");
while(!s.equals("s") || !s.equals("S"))
{
s = in.nextLine();
}
this.listening = false;
}
#Override
public void run() {
this.listening = true;
while(listening)
{
Socket newPlayer;
try {
newPlayer = connection.accept();
} catch (IOException e) {
newPlayer = null;
}
if (newPlayer != null) {
if (this.nextPeer == null) {
this.nextPeer = newPlayer;
try {
this.messaging = new MessageCenter(newPlayer);
} catch (IOException e) {
System.out.println("Error making MessageCenter");
}
} else {
String[] message = { newPlayer.getInetAddress().getHostName(),
String.valueOf(newPlayer.getPort()) };
Thread worker = new Thread(new MessagerThread("NP", message, this.messaging));
worker.run();
}
}
}
}
Now I am stuck because I cant quite find out how to let the last player to join know the port number used by the player to begin the name, or the host. Looking at the image of the ring architecture above, how does system 9 make the connection to system 1? Can I use the port number I supplied to the ServerSocket object for this?
I'm doing a client/server program in Java (including a GUI).
I've got the following code in the client:
public class SBListener implements ActionListener{
public void actionPerformed(ActionEvent e){
try{
outToServer.writeUTF(usn.getText().trim());
System.out.println("sent username to server");
playerExists = inToClient.readBoolean();
System.out.println("past getting player");
System.out.println("player exists = " + playerExists);
}catch(IOException a){
System.err.println(a);
}
if(playerExists == false){
JButton submitInfo = new JButton("submit info");
submitInfo.addActionListener(new SBNewInfoListener());
init.add(new JLabel(""));//dummy element to get the right alignment
init.add(new JLabel("First Name:"));
init.add(fn);
init.add(new JLabel("Last Name:"));
init.add(ln);
init.add(submitInfo);
add(init, BorderLayout.WEST);
init.setVisible(true);
init.revalidate();
init.repaint();
}
}
}
And the following code in the Server:
String username = inp.readUTF();
System.out.println(username);
out.writeBoolean(false);
System.out.println("wrote boolean, waiting for fn/ln/un");
fn = inp.readUTF();
System.out.println("got fn");
ln = inp.readUTF();
un = inp.readUTF();
But when the button that calls SBListener is clicked, the program freezes when it gets to the point where the Server is waiting for fn/ln/username. I added a bunch of system.out statements for debugging and I get up to the one that says "wrote boolean, waiting for fn/ln/un".
Basically, I'm trying to update the screen after the Server returns a false value. Specifically, I want to add two text fields for first & last name. I then want to send those values to the server.
Can anyone tell me how to fix this? Thanks in advance for any help!
Don't execute client/server code in an ActionListener. This will cause the Event Dispatch Thread to block while waiting for a response from the server. When EDT is blocked the whole GUI freezes.
Read the section from the Swing tutorial on Concurrency for more information. You need so use a separate Thread for the client/server code. Or you can use a SwingWorker as discussed in the tutorial.
My guess is that outToServer isn't being flushed. I would guess (although I can't tell from your sample code) that outToServer is a DataOutputStream. You need to call .flush to get the data out of the buffer and onto the wire.
Try this:
outToServer.writeUTF(usn.getText().trim());
outToServer.flush();
I am using the javax.comm package to read some data off the serial port.
The data is to be displayed on a SWT a text widget. I have added an
eventListener to the serial port object and made notifyOnDataAvailable
true, so that my app gets notified when data arrives. Anyway, on the
event handler, I try to append the newly read data to the text widget,
but it does not append the read value with text widget. But when i try to print the same in console it does that perfectly. I have a similar app
written in AWT and it doesn't have this problem. Does it have anything
to do with the way SWT handles the main thread? Is there a way around my
problem?
Here is my code -
public void serialEvent(SerialPortEvent evt) {
if (evt.getEventType() == SerialPortEvent.DATA_AVAILABLE)
{
try
{
byte singleData = (byte)input.read();
// READING THE SERIAL PORT VALUE HERE IN
// TEXT AREA CALLED txtLog
if (singleData != NEW_LINE_ASCII)
{
logText = new String(new byte[] {singleData});
// System.out.print(logText);
txtLog.append(logText);
}
else
{
txtLog.append("\n");
}
}
catch (Exception e)
{
logText = "Failed to read data. (" + e.toString() + ")";
txtLog.setForeground(Color.red);
txtLog.append(logText + "\n");
}
}
}
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();