Avatar billede langkiller Nybegynder
05. marts 2013 - 00:16 Der er 25 kommentarer og
1 løsning

Socket program - flere Clients til en server

Er ny til socket programmering i java og har lidt problemer i forb. med at have flere "Client's" forbundet til en server, som skal have mulighed for at skrive til hinanden.

Jeg har et program hvor server og client kan skrive til hinanden efter tur (TCP), men kan ikke finde logikken i det og få lavet det andet. En løsning og forklaring på dette ville være en virkelig stor hjælp.

Her er min TCPServer.java: http://pastebin.com/0SVV0ZnX

og min TCPClient.java: http://pastebin.com/VqQh7mYD
Avatar billede langkiller Nybegynder
05. marts 2013 - 00:23 #1
Helst en så simpel forklaring som mulig :) er stadig lige ved at forstå nogle af grundprincipperne for socketprogrammering
Avatar billede arne_v Ekspert
05. marts 2013 - 00:32 #2
Du skal vel have en data struktur som har referance til alle klienter.

En List/ArrayList eller Map/HashMap.
Avatar billede langkiller Nybegynder
05. marts 2013 - 01:05 #3
ja okay, jeg vil lige prøve at give det et forsøg imorgen. hmm kunne du forklare det lidt mere præcist?
Avatar billede arne_v Ekspert
05. marts 2013 - 01:29 #4
Naar du accepterer en connection, saa gemmer du en referance til et objekt som haandterer den klient. Saa har du mulighed for at skrive til alle klienter eller for at finde en ebstemty klient frem hvis der skal skrives til en enkelt.
Avatar billede langkiller Nybegynder
05. marts 2013 - 12:13 #5
har forsøgt mig arraylist osv for at gøre det muligt at tilgå flere klienter.. Har en nullpointerexception fejl lige nu og ved ikke helt hvorfor, kan ikke finde ud af hvad der er galt.

Her er min TCPServer:


import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

public class TCPServer {

    private static Thread threadClients;
    private static Thread threadWriteToClients;
    private static Thread threadServerCommands;
    private static ServerSocket welcomeSocket;
    private static List<Socket> clientsArray = new ArrayList<Socket>();
    private static boolean go_on = true;
    private static String sentence;
    private static String serverCMD;
    private static BufferedReader inFromClient;
    private static Socket connectionSocket;
    private static DataOutputStream outToClient;
   
    public static void main(String argv[]) throws Exception
    {
        System.out.println("starting main");        
        welcomeSocket = new ServerSocket(9876);
        System.out.println("Server socket klar");
       
        inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
       
        // Laver sockets til hver enkel Client (accepterer)
        threadClients = new Thread(new Runnable() {
                public void run() {
                    while(go_on) {
                        try {
                            connectionSocket = welcomeSocket.accept();
                            clientsArray.add(connectionSocket);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            });
        threadClients.start();

     
     
      // Traad til at skrive til samtlige clients
        threadWriteToClients = new Thread(new Runnable() {
                public void run() {
                    while(go_on) {
                        try {
                            sentence = inFromClient.readLine();
                            for (int i = 0; i <= clientsArray.size(); i++) {
                                outToClient = new DataOutputStream(clientsArray.get(i).getOutputStream());
                                outToClient.writeBytes("FROM SOME CLIENT: " + sentence + "\n");    
                            }                       
                           
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                       
                    }
                }
            });
        threadWriteToClients.start();
       
       
       
      // SERVER kommandoer (gaar ogsaa ud til clients)
        threadServerCommands = new Thread(new Runnable() {
                public void run() {
                    BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in)); 
                    while(go_on) {
                        try {
                            serverCMD = inFromUser.readLine();
                            for (int i = 0; i <= clientsArray.size(); i++) {
                                outToClient = new DataOutputStream(clientsArray.get(i).getOutputStream());
                                outToClient.writeBytes(serverCMD + "\n");    
                            }   
                           
                            if (serverCMD.equals("quit")) {
                                go_on = false;
                                System.out.println("quitting the loop and closing the socket");
                                  connectionSocket.close();
                                  welcomeSocket.close();
                            }
                           
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                       
                    }
                }
            });
        threadServerCommands.start();
 
       
        }
   
}



FEJL MEDD: starting main
Server socket klar
Exception in thread "main" java.lang.NullPointerException
    at TCPServer.main(TCPServer.java:32)

linje 32 er:  inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
Avatar billede arne_v Ekspert
05. marts 2013 - 18:27 #6
naar du udfoerer:

        inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
     
foer:
                            connectionSocket = welcomeSocket.accept();

saa er connectionSocket jo null.
Avatar billede langkiller Nybegynder
06. marts 2013 - 00:47 #7
ahh ja selvfølgelig! har rykket rundt på det så har ingen fejl i mit program nu.. men kan ikke se beskeder fra andre clients når jeg kører det og prøver at skrive beskeder. har du en idé om hvor fejlen kan ligge. er rimelig blank her :/
Avatar billede arne_v Ekspert
06. marts 2013 - 03:19 #8
hvordan ser koden ud nu?
Avatar billede langkiller Nybegynder
06. marts 2013 - 12:41 #9
Avatar billede arne_v Ekspert
06. marts 2013 - 22:09 #10
threadWriteToClients skal vel ikke accept'e?

for tekst boer du bruge PrintStream ikke DataOutputStream!

proev og kald flush efter write!
Avatar billede langkiller Nybegynder
06. marts 2013 - 23:33 #11
hvis jeg fjerne accept fra threadWriteToClients laver den en nullpointerexception på linje 57 som er: sentence = inFromClient.readLine();

Hvis jeg skal bruge PrintStream i stedet for, hvad skal jeg så skrive i min write? der står at den skal have "byte" som input..
kan ikke skrive følgende da det giver en syntakst fejl:
outToClient = new PrintStream(clientsArray.get(i).getOutputStream());                            outToClient.write( "FROM SOME CLIENT: " + sentence + "\n");
Avatar billede arne_v Ekspert
06. marts 2013 - 23:42 #12
da:

connectionSocket = welcomeSocket.accept();

ikke deler noget med:

sentence = inFromClient.readLine();

saa kan det vist ikke haenge saadan sammen.
Avatar billede arne_v Ekspert
06. marts 2013 - 23:43 #13
outToClient = new PrintStream(clientsArray.get(i).getOutputStream());                            outToClient.println( "FROM SOME CLIENT: " + sentence);
Avatar billede langkiller Nybegynder
07. marts 2013 - 00:54 #14
får stadig nullpointerexception på
sentence = inFromClient.readLine();
Avatar billede arne_v Ekspert
07. marts 2013 - 01:10 #15
saa er inFromClient null
Avatar billede arne_v Ekspert
07. marts 2013 - 01:11 #16
Jeg kan ioevrigt se at inFromClient er static saa designet vil aldrig kunne haandtere mere end 1 klient
Avatar billede langkiller Nybegynder
07. marts 2013 - 01:29 #17
hmm okay.. hvis jeg fjerne static så der kun står private inFromClient som global variabel, klager eclipse og siger at den skal være static.. jeg droppede den så helt som global variabel og smed den ned i tråden "threadWritToClients" så der nu står:

connectionSocket = welcomeSocket.accept();
                            BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
                            sentence = inFromClient.readLine();

(der kom stadig nullpointerexception uden:
connectionSocket = welcomeSocket.accept();

programmet kan godt køre men clients kan ikke se hinandens beskeder
Avatar billede arne_v Ekspert
07. marts 2013 - 02:26 #18
connectionSocket = welcomeSocket.accept();

goer vel at du aldrig kommer videre i programmet, saa det er ikke nogen loesning
Avatar billede langkiller Nybegynder
07. marts 2013 - 02:42 #19
og hvis jeg fjerne den får jeg nullpointerexception:
java.lang.NullPointerException
    at TCPServer$2.run(TCPServer.java:56)
    at java.lang.Thread.run(Unknown Source)

linje 56:
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
Avatar billede langkiller Nybegynder
07. marts 2013 - 02:43 #20
det betyder vel at connectionSocket er null ikke?
ved bare ikke hvad jeg skal skrive så :/
Avatar billede arne_v Ekspert
07. marts 2013 - 02:50 #21
ja

skulle connectionSocket have faaet en vaerdi paa det sted i programmet?
Avatar billede langkiller Nybegynder
07. marts 2013 - 10:14 #22
nej det den vel ikke .. hmm ved bare ikke hvad den burde indeholde.
Avatar billede langkiller Nybegynder
07. marts 2013 - 10:25 #23
okay jeg troede jeg havde fundet en løsning, men det viste sig også at være galt.. min for løkke i threadWriteToClients ser nu sådan ud:

for (int i = 0; i < clientsArray.size(); i++) {   
                            connectionSocket = clientsArray.get(i);
                            BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
                            sentence = inFromClient.readLine();
                                outToClient = new PrintStream(clientsArray.get(i).getOutputStream());
                                outToClient.println("FROM SOME CLIENT: " + sentence + "\n");    
                                outToClient.flush();
                            }



Den opfører sig bare lidt mærkeligt nu.. når jeg køre to clients op mod serveren skriver den de fleste gange den besked man lige har indtastet så man selv kan se den (andre klienter kan ikke se den) og nogle gange står der "FROM SOME CLIENT" foran, men ikke hver gang.. ?? Og ind imellem laver den linje skift hos den anden klient når man indtaster en besked.. men det er også kun nogle gange. hara virkelig ingen ide om hvorfor den gør dette?
Avatar billede arne_v Ekspert
07. marts 2013 - 22:55 #24
Alle de static fields i en multithreaded context skal gaa galt.
Avatar billede langkiller Nybegynder
03. april 2013 - 22:50 #25
undskyld, jeg glemte helt tråden her. Fik det til at køre som det skulle. Tak for hjælpen ! Smid et svar
Avatar billede arne_v Ekspert
03. april 2013 - 23:48 #26
kommer her
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester