TCP komunikace a přístup do vláken – Java – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama
Reklama

TCP komunikace a přístup do vláken – Java – Fórum – Programujte.comTCP komunikace a přístup do vláken – Java – Fórum – Programujte.com

 

Hledá se programátor! Plat 1 800 € + bonusy (firma Boxmol.com)
technik0
~ Anonymní uživatel
5 příspěvků
29. 5. 2013   #1
-
0
-

zdravím, snažím se udělat gui klienta pro komunikaci se serverem. Abych to lépe vysvětlil:

Mám 3 vlákna: 1) GUI Okno, kterej zavolá metodu connect a připojí se na server - vytvoří nové vlákno, ve kterém má probíhat komunikace a sám sebe zavře. 2) GUI okno, které má komunikovat se serverm (odesílat a přijímat data) 3) To je již zmíněné vlákno spuštěné 1. oknem.

Jak docílit toho abych do toho 3. vlákna mohl přistupovat a volat třeba metodu na posílání a přijímání dat z právě běžícího spojení? Zkoušel sem toto:

package com.is.admin.net;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;



public class connect {
    public static String get = null;
    public static String send = null;
    public static boolean cekam = false;
    public static boolean prijem = false;
    public static boolean connected = false;

    public static String trans(String to) {
        String from = null;
        cekam = true;
        prijem = false;
        
        send = to;

        while(cekam) {
            if(prijem = true) {
                from = get;
                get = null;
                cekam = false;
            }
        }
        return from;
    }

    public static void conn(String host, int port) {
        boolean trans = true;
        try {       
            Socket client=new Socket(host,port);
            System.out.println("Jsem pripojen!");
            connected = true;
            //Streamy
            PrintStream out=new PrintStream(client.getOutputStream());
            BufferedReader in= new BufferedReader(new InputStreamReader(client.getInputStream()));
            
            out.print("FirstWelcomeWord\n");
            out.flush();
            String temp;

            
            while(trans) {
                if (send != null) {
                    out.print(send);
                    out.flush();
                    send = null;                    
                }
                
                if(in.ready()) {
                    temp = in.readLine();
                } else temp = null;
                
                if(temp != null) {
                    get = temp;
                    prijem = true;
                }

                
                if("PleaseEnd".equals(temp)) trans = false;  //pokud prijmem prazdny socket s null nebo ukonceni - vypnem to
            }
            
            in.close();
            out.close();
            client.close();
                        
        } catch (UnknownHostException ex) {
            System.out.println("Chyba pri pripojovani:" + ex);
        } catch (IOException ex) {
            System.out.println("Chyba pri pripojovani:" + ex);
        }
    }
}

A vytvoření vlákna pro komunikaci:

            Thread t = new Thread() {
            @Override
            public void run() {
              connect.conn(host, port);  
           }
        };
        t.start();

Melo to fungovat tak ze kdyz odkudkoliv zavolam trans(String to); čímž bych měl odeslat data na server a následně přijmout zpět, ale bohužel to prostě nefunguje (do tý metody trans potřebuju líst z jiného vlákna)...

Snad pochopíte muj problem... Díky za každou pomoc

Nahlásit jako SPAM
IP: 93.99.138.–
Reklama
Reklama
sleepy0
Stálý člen
31. 5. 2013   #2
-
0
-

Skus to nerobit cele staticke a rozdel to na 2 vlakna jedno co zapisuje do Socketu a druhe co z neho cita. Co som si vsimol u teba, tak program celu dobu iba caka na prijem spravy. Cize pokial ti niekto nieco neposle ty mu tiez nic neposles. Ak robis nieco ako echo server, ktory musi najskor nieco priat az potom nieco posle spat, tak ti to nepojde, myslim ze informatici tomu hovoria deadlock. Tu som napisal nieco, ako by som postupoval ja, nieje to dokonale a neskusal som to, ale mohlo by to s drobnymi upravami fungovat (a samozrejme s dopisanim kodu :D ). A malo by to posielat z lubovolneho vlakan, ktore ma referenciu na objekt Connection.

public class Connection{
	private booelan connected = false;
	private Socket connectionSocket = null;
	private MyReader reader = null;
	private MyWriter writer = null;
	private Thread readerThread = null;
	private Thread writerThread = null;
	
	public Connection(String ip, int port){
		connectTo(ip, port);
	}

	public void close(){
		// uzavret porty
		// a zastavit reader a writer
	}
	
	public void sendMsg(String msg){
		writer.writeMsg(msg);
	}

	public Socket getSocket(){
		return this.socket;
	}

	public String recieveMsg(){
		return reader.readMsg();
	}

	public synchronized boolean isConnected(){
		return connected;
	}

	private synchronized void setConnected(boolean connected){
		this.connected = connected;
	}

	public void connectTo(String ip, int port){
		try {       
			Socket client=new Socket(host,port);
			setConnected(true);
			reader = new MyReader(this);
			readerThread = new Thread(reader);
			readerThread.start();
			writer = new MyWriter(this);
			writerThread = new Thread(writer);
			writerThread.start();
            	}
		catch(IOException ioe){
			// odhitit a spracovat vynimku
		}
		catch(UnknownHostException uhe){
			// odhitit a spracovat vynimku
		}
	}
}

public class MsgReader implements Runnable{
	private BufferedReader reader;
	private Connection connection;
	private Thread currentThread = null;
	private String msg = null;
	private boolean recieved = false;
	
	public MsgReader(Connection connection){
		this.connection = connection;
		reader = new BufferedReader(new InputStreamReader(connection.getSocket()));
	}	

	public void run(){
		try{
			while(connection.isConnected()){
				String msg = reader.readLine(); // Zda sa mi ze sa blokuje do vtedy pokial nieje ready
				setMessage(msg);
			}
		}	
	}

	private synchornized setMessage(String msg){
		recieved = true;
		this.msg = msg;
	}

	private synchronized getMessage(){
		recieved = false;
		return this.msg;
	}

	private synchornized isRecieved(){
		return this.recieved;
	}

	public String readMsg() throws InterruptedException{
		currentThread = System.currentThread();
		while(!isRecieved()){
			currentThread.wait();
		}
		return getMessage();
	}

	public void close(){
		currentThread.intrrupt();
		currentThread = null;
		reader.close();
	}
}

public class MyWriter implements Runnable{
	// podobne ako reader
}
Nahlásit jako SPAM
IP: 213.215.67.–
technik0
~ Anonymní uživatel
5 příspěvků
2. 6. 2013   #3
-
0
-

Ja uz to kompletne prekopal, uz jsem z toho magořil... Ale stejne mi to nejde :(

Mam kod:

public class connect implements Runnable {
    String host;
    int port;
    
    String send2srv = null;
    String getFromSrv = null;
    boolean connected = false;
        
    public void setHost(String h) {
        this.host = h;
    }
    
    public void setPort(int p) {
        this.port = p;
    }
    
    public synchronized String retrive(String r) {
        this.send2srv = r;
        return r+host;
    }
    
    @Override
    public void run() {    
         try {
           Socket conn = new Socket(host,port);
            if(conn.isConnected()) {
                 main.addLog("Jsem pripojen k " + conn.getInetAddress());
             }
            

        BufferedReader cteni = new BufferedReader(
            new InputStreamReader(conn.getInputStream()));
        BufferedWriter zapis = new BufferedWriter(
            new OutputStreamWriter(conn.getOutputStream()));
        
            //Poslu prvni uvitaci zpravu
            zapis.write("Hi!");zapis.flush();
            main.addLog("1");
            zapis.write("Hi!");zapis.flush();
            
            System.out.println(cteni.readLine());
            
            zapis.close();
            cteni.close();
            conn.close();
        } 
        catch (UnknownHostException ex) { System.out.println(ex.toString()); } 
        catch (IOException ex) { System.out.println(ex.toString()); }
    }
 
}

to uz je otevrene v novem vlakne, ale pri zapis.write("Hi!");zapis.flush(); se na server vubec ten string neposle a uz nevim proc... Param se s tim 5ty den a nemuzu si pomoct...

Jestli bych te mohl poprosit o jabber nebo nejaky rychlejsi komunikacni protokol? Jsem ochotny uz i neco zaplatit jako odmenu za pomoc (Neni to zadna maturitni prace ani nic jineho!)

Dekuji za ochotu

Nahlásit jako SPAM
IP: 149.255.82.–
sleepy0
Stálý člen
2. 6. 2013   #4
-
0
-

Ahoj tu je nieco co som teraz na rychlo zbuchol, jabber na mna je: sleepY771[na]jabber[bodka]cz . Tu je ten kod, opraveny a dorobeny, ale stale su tam nejake chyby, no nemam na to teraz cas: 

Connection.java:

import java.io.IOException;
import java.net.Socket;


public class Connection {

	private boolean connected = false;
	private Socket connectionSocket = null;
	private MyReader reader = null;
	private MyWriter writer = null;
	private Thread readerThread = null;
	private Thread writerThread = null;
	
	public Connection(String ip, int port){
		connectTo(ip, port);
	}

	public void close(){
		try {
			connectionSocket.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		reader.close();
		writer.close();
		setConnected(false);
		synchronized(readerThread){
			readerThread.notify();
		}
		writerThread.interrupt();	
		
	}
	
	public void sendMsg(String msg){
		writer.writeMsg(msg);
	}

	public Socket getSocket(){
		return this.connectionSocket;
	}

	public String recieveMsg(){
		String message = null;
		try {
			message = reader.readMsg();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return message;
	}

	public synchronized boolean isConnected(){
		return connected;
	}

	private synchronized void setConnected(boolean connected){
		this.connected = connected;
	}

	public void connectTo(String ip, int port){
		try {       
				this.connectionSocket = new Socket(ip,port);
				setConnected(true);
				reader = new MyReader(this);
				readerThread = new Thread(reader);
				readerThread.start();
				writer = new MyWriter(this);
				writerThread = new Thread(writer);
				writerThread.start();
			}
			catch(IOException ioe){
			// odchitit a spracovat vynimku
			}
	}
	
	public static void main(String arg[]){
		Connection con = new Connection("127.0.0.1", 4444);
		con.sendMsg("Hi!");
		System.out.println("Got message: "+ con.recieveMsg());
		con.sendMsg("exit");
		con.close();
	}

}

MyReader.java:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;


public class MyReader implements Runnable {
	
	private BufferedReader reader;
	private Connection connection;
	private Thread currentThread = null;
	private String msg = null;
	private boolean recieved = false;
	
	public MyReader(Connection connection){
		this.connection = connection;
		try {
			reader = new BufferedReader(new InputStreamReader(connection.getSocket().getInputStream()));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}	

	public void run(){
		try{
			while(connection.isConnected()){
				String msg = reader.readLine(); // Zda sa mi ze sa blokuje do vtedy pokial nieje ready
				System.out.println("Got msg: "+msg);
				setMessage(msg);
				System.out.println("Msg set");
				//synchronized (currentThread) {
				//	currentThread.notify();
				//}
			}
		}
		catch(IOException ioe){
			
		}
	}

	private synchronized void setMessage(String msg){
		this.recieved = true;
		this.msg = msg;
		synchronized (currentThread) {
			currentThread.notify();
		}
	}

	private synchronized String getMessage(){
		recieved = false;
		return this.msg;
	}

	private synchronized boolean isRecieved(){
		return this.recieved;
	}

	public String readMsg() throws InterruptedException{
		currentThread = Thread.currentThread();
		synchronized (currentThread) {
			while(!isRecieved()){
				currentThread.wait();
			}
		}
		
		return getMessage();
	}

	public void close(){
		try {
			reader.close();
			System.out.println("Reader closed!");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		currentThread.interrupt();
		currentThread = null;
		
	}

}

MyWriter.java:

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;

public class MyWriter implements Runnable {

	private Connection connection = null;
	private PrintWriter writer = null;
	private String msg = null;
	private boolean waitForMsg = true;
	private Thread writerThread = null;

	public MyWriter(Connection connection) {
		this.connection = connection;
		try {
			this.writer = new PrintWriter(new OutputStreamWriter(connection.getSocket().getOutputStream()));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public synchronized void writeMsg(String msg) {
		this.msg = msg;
		waitForMsg = false;
	}

	public synchronized String getMsg() {
		waitForMsg = true;
		return this.msg;
	}
	
	public synchronized boolean isWaiting(){
		return waitForMsg;
	}

	@Override
	public void run() {
		writerThread = Thread.currentThread();
		while (connection.isConnected()) {

			try {
				synchronized (writerThread) {
					if (isWaiting() && connection.isConnected()) {
						writerThread.wait();
					}
				}
				System.out.println("Writing msg: "+getMsg());

				writer.println(getMsg());
				writer.flush();
			} catch (InterruptedException e) {
				
			}
		}
	}
	
	public void close(){
		writerThread.interrupt();
		writerThread = null;
		writer.close();
	}

}

a ako server som pouzil EchoServer, kody su aj na nete ale tu ti ho dam, mierne upraveny:

EchoServer.java:

/*************************************************************************
 *  Compilation:  javac EchoServer.java
 *  Execution:    java EchoServer port
 *  Dependencies: In.java [VERSION IN THIS DIRECTORY ONLY] Out.java
 *  
 *  Runs an echo server which listents for connections on port 4444,
 *  and echoes back whatever is sent to it.
 *
 *
 *  % java EchoServer 4444
 *
 *
 *  Limitations
 *  -----------
 *  The server is not multi-threaded, so at most one client can connect
 *  at a time.
 *
 *************************************************************************/

import java.net.Socket;
import java.net.ServerSocket;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

public class EchoServer {
	
    public static void main(String[] args) throws Exception {
		boolean running = true;
        // create socket
        int port = 4444;
        ServerSocket serverSocket = new ServerSocket(port);
        System.err.println("Started server on port " + port);

        // repeatedly wait for connections, and process
        while (running) {

            // a "blocking" call which waits until a connection is requested
            Socket clientSocket = serverSocket.accept();
            System.err.println("Accepted connection from client");

            // open up IO streams
            BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
			PrintWriter writer = new PrintWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
            // waits for data and reads it in until connection dies
            // readLine() blocks until the server receives a new line from client
            String s;
            while ((s = reader.readLine()) != null) {
				System.out.println("Recieving message: "+s);
                writer.println(s);
                writer.flush();
                if(s.equals("exit")){
					running = false;
				}
            }

            // close IO streams, then socket
            System.err.println("Closing connection with client");
            writer.close();
            reader.close();
            clientSocket.close();
        }
    }
}
Nahlásit jako SPAM
IP: 158.195.204.–
eXilim0
Duch
3. 6. 2013   #5
-
0
-

Pěkné, aspon vím proč mi to nešlo, akorát ted se mi stále nedářaí to pustit jako vlákno? V podtstae v gui když zmáčknu tlačítko potřebuju vytvořit spojení a dalším tlačítkem potřebuju posílat a přijímat data?

Nahlásit jako SPAM
IP: 93.99.138.–
eXilim0
Duch
3. 6. 2013   #6
-
0
-

Zkusil sem si udelat jeste tridu ktera by se starala o vsecko:

package com.is.admin.net;


public class transfer extends Thread {
    private String host = null;
    private int port;
    private String out=null;
    private String in = null;
    
    public transfer() {
        
    }

    public void setHost(String h) {
        this.host = h;
    }
    public void setPort(int p) {
        this.port = p;
    }
    public String send(String s) {
        String ret = null;
        boolean exit = false;
        
        this.out = s;
        while(!exit) {
            if (in!=null) {
                ret = in;
                in = null;
                exit = true;
            }
        }
        return ret;
    }
    @Override
    public void run() {
        boolean exit = false;
        Connection conn = new Connection(host, port);
        
        while(!exit) {
            if(out != null)  {
                conn.sendMsg(out);
                out = null;
                in = conn.recieveMsg();
                if(in == "exit") exit = true;
            }
            
        }
        conn.close();
    }
}

kde bych ji nastartoval pomoci 

public static transfer tr = new transfer();
public void start() {
            tr.setHost("localhost");
            tr.setPort(2222);
            tr.start();
}
a potom odkudkoliv bych posiall / prijimal data pomoci tr.send("");
Ale to mi nejde
Nahlásit jako SPAM
IP: 93.99.138.–
ingiraxo+15
Grafoman
3. 6. 2013   #7
-
0
-
Nahlásit jako SPAM
IP: 213.168.183.–
Moje aplikace: http://ophite.cz
Tutoriály na: C#
technik0
~ Anonymní uživatel
5 příspěvků
3. 6. 2013   #8
-
0
-

Chtel bych aby to bylo pri staru ještě

Nahlásit jako SPAM
IP: 149.255.82.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 30 hostů

Podobná vlákna

TCP server, TCP klient v Linuxu — založil kocourOggy

Více vláken — založil Václav Valíček

Debug vlaken - Netbeans — založil drobas

Synchronizace více vláken — založil Blujacker

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032016 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý