Problem z Socketami

0

Witam, chcę zrobić 'grę' przeciąganie liny gdzie liną jest progressbar. Gracz będzie mógł wybrać stronę po której będzie stał (chcę aby mogło grać kilku graczy jednocześnie) i w momencie gdy ktoś kliknie na przycisk serwer zaktualizuje aktualny stan progressbara ( o 1 w dół lub 1 w górę zależnie od drużyny) i roześle informacje z aktualnym stanem progressbara do wszystkich clientów. Z całym GUI sobie poradzę, natomiast nie mogę zrobić aby w momencie dołączenia do gry nowy client otrzymał aktualny stan liny (progressbara). Aktualnie mam, że naklikam np do 55% ale jak odpale nowego clienta to nowy client ma od nowa 50%. Aktualnie mam napisane coś takiego:

import java.io.*;
import java.text.*;
import java.util.*;
import java.net.*;
public class Server {

 public int postep=50;
	
	public void startServer() throws IOException 
    {

        ServerSocket ss = new ServerSocket(5056);

        while (true) 
        {
            Socket s = null;
             
            try
            {
                s = ss.accept();
                 
                System.out.println("Połączono klienta ");
                 
                DataInputStream dis = new DataInputStream(s.getInputStream());
                DataOutputStream dos = new DataOutputStream(s.getOutputStream());
 
                Thread t = new ClientHandler(s, dis, dos,postep);
                t.start();
                 
            }
            catch (Exception e){
                s.close();
                e.printStackTrace();
            }
        }
    }
}

class ClientHandler extends Thread 
{
    final DataInputStream dis;
    final DataOutputStream dos;
    final Socket s;
	public int postep;
     
 
    // Constructor
    public ClientHandler(Socket s, DataInputStream dis, DataOutputStream dos, int postep) 
    {
        this.s = s;
        this.dis = dis;
        this.dos = dos;
        this.postep = postep;
       }
 
    @Override
    public void run() 
    {
        int received;
        int toreturn;
        while (true) 
        {
            try {
 
                dos.writeUTF("1 aby dodac 0 aby odjac");
                dos.write(postep);
                 
                received = dis.read();
                 
                if(received == 5)
                { 
                	System.out.println("Wylaczam polaczenie");
                   this.s.close();
                    break;
                }
                 
                 
                switch (received) {
                 
                    case 0:
                    	postep=postep-1;
                        break;
                         
                    case 1 :
                    	postep= postep+1;

                        break;
                    case 2 :
                        dos.write(postep);
                        break;
                         
                    default:
                        dos.writeUTF("Invalid input");
                        break;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
         
        try
        {
            this.dis.close();
            this.dos.close();
             
        }catch(IOException e){
            e.printStackTrace();
        }
    }
 
 }
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.net.*;
import java.util.Scanner;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
 
public class Client extends JFrame implements ActionListener{
	JButton polacz,dodaj;
	JProgressBar postep;
    int p=0;
	public Client() {
		
		setTitle("Client Przeciagania Liny");
		setSize(800,400);
		setVisible(true);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setLayout(null);
		
		polacz = new JButton("Polacz");
		polacz.setBounds(250,150,80,30);
		add(polacz);
		polacz.addActionListener(this);
		
		dodaj = new JButton("Dodaj punkt");
		dodaj.setBounds(200,200,300,100);
		add(dodaj);
		dodaj.addActionListener(this);
		
		postep = new JProgressBar(0,100);
		postep.setStringPainted(true);
		postep.setValue(0);
		postep.setBounds(50,50,700,50);
		add(postep);
		
	}

	public void startClient() throws IOException 
    {
        try
        {
            Scanner scn = new Scanner(System.in);
             
            InetAddress ip = InetAddress.getByName("localhost");
     
            Socket s = new Socket(ip, 5056);
     
            DataInputStream dis = new DataInputStream(s.getInputStream());
            DataOutputStream dos = new DataOutputStream(s.getOutputStream());
     

            while (true) 
            {
                System.out.println(dis.readUTF());
                p=dis.read();
                postep.setValue(p);
                int tosend = scn.nextInt();
                dos.write(tosend);
                 

                if(tosend == 5)
                {
                    System.out.println("Closing this connection : " + s);
                    s.close();
                    System.out.println("Connection closed");
                    break;
                }
                if(tosend == 2)
                {
                    System.out.println(dis.read());
                }
                 
            }
             
            // closing resources
            scn.close();
            dis.close();
            dos.close();
        }catch(Exception e){
            e.printStackTrace();
        }
    }

	@Override
	public void actionPerformed(ActionEvent arg0) {
		
	}
}
0

Musisz się zastanowić, gdzie będziesz przechowywał aktualny stan gry. Aktualnie masz to w 2 miejscach (a właściwie w n miejscach), niezsynchronizowanych ze sobą. Nie będę Ci odbierał przyjemności z samodzielnego rozwiązania :)

0

Przyjemność przyjemnością, siedzę nad tym już trochę, a czas się kończy w sobotę muszę oddać projekt na uczelni, a jeszcze czeka mnie kolejny z wykorzystaniem RMI także na tą sobotę :D

1

Przekaż temu handlerowi obiekt serwera, jako this. Wtedy będziesz mógł zmodyfikować pole postep należące do serwera. Teraz, jak masz to wywołanie

             Thread t = new ClientHandler(s, dis, dos,postep);

To jest to przekazanie przez wartość. Czyli dalsza modyfikacja zmiennej postep nie ma wpływu na wartość zmiennej przekazanej do wywołania funkcji. Łatwiej byłoby to widać, gdybyś dał inne nazwy tym zmiennym, np. postepS, postepC.

Zmodyfikowany konstruktor handlera mógłby wyglądać tak:

 public ClientHandler(Socket s, DataInputStream dis, DataOutputStream dos, int postepC, Server server)
0

Albo nie do końca rozumiem jak to ma być zrobione, albo nadal nie działa ;/
@Edit
Jednak działa nie w tym miejscu tworzyłem obiekt klasy.

1 użytkowników online, w tym zalogowanych: 0, gości: 1