# Wenn socket geöffnet, warten dann öffnen !



## knopper (15. März 2005)

Hallo,

 Ich habe einProzess A, welches ein Socket ständig <100 ms oeffnet,lesen  und schreiben.

 Nun kommt ein Prozess B, welches auch dieses Socket öffnen will. 
 Wie kann ich der Prozess B steuern, dass er wartet bis das Socket wieder frei ist, 
 Muss man mit Thread arbeiten oder geht es irgendwie mit einer For Schleife ?

 Gruss


----------



## 4men (15. März 2005)

Hi

Könntest du mir bitte noch diese Fragen beantworten?

1. Handelt es sich um 2 Programme oder um zwei Programmteile die das Socket nutzen sollen?
2. Soll das Programm als Server oder Client fungieren?
3. Was stellst du dir konkret vor wie das am Ende funktionieren soll?

mfg 4men


----------



## knopper (15. März 2005)

Hallo ?

1. Es handelt sich um 2 Programmteile

2. Client

3. Wo gibt es Beispiele von Socket mit Semaphoren ?
Gruss


----------



## 4men (15. März 2005)

Du Legst eine Klasse an die dein Socket initialiesiet und dir die Methoden für Lesen, Schreiben, Öffnen und Schließen bereitstellt. Des weiteren muss ein boolean her mit passender get und set Methode welcher angibt ob das Socket benutzt wird.

Als nächstes legst du die Threads an. Die Prozesse bekommen immer wieder mal etwas Zeit zugeteil und in dieser schauen sie nun ob das Socket frei ist. Wenn das der Fall ist belegen sie es. Wenn sie schließlich fertig sind geben sie das Socket wieder frei und werden terminiert.

Wenn du es jetzt so realiesren willst das ein bestimmter Ablauf eingehalten wird dann musst du das ganze noch um einen Zähler erweitern d.h. der Prozess bekommt das Socket nur wenn er auch die richtige Position in der Reihe hat. Die Position bekommen sie bei der Initialiesierung gesetzt.

Sollen die Prozesse endlos laufen und die Anzahl ist bekannt kannst du einen Reset einbauen welcher beim erreichen der letzen Position den Zähler zurücksetzt. Ist die Anzahl unbekannt kannst du das nur durch die Zeit wo du sie schlafen legst Regeln.

mfg 4men


----------



## Thomas Darimont (15. März 2005)

Hallo!

Schau doch mal hier:
(Java 5)

```
/**
 * 
 */
package de.tutorials;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.Semaphore;

/**
 * @author Administrator
 * 
 */
public class SocketSynchronizer {

	private Socket socket;

	private Semaphore semaphore = new Semaphore(1);

	private BufferedWriter bw;

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception {
		new SocketSynchronizer().start();
	}

	private void start() throws Exception {

		Runtime.getRuntime().addShutdownHook(new Thread() {
			public void run() {
				System.out.println("Shuting down...");
				try {
					if (bw != null) {
						bw.close();
					}
					if (socket != null) {
						socket.close();
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		});

		startServer(7777);
		initSocket("localhost", 7777);

		startClient("A");
		startClient("B");
		startClient("C");

	}

	private void startClient(String name) {
		new Thread(name) {
			public void run() {
				while (true) {
					try {
						semaphore.acquire();

						bw.write(this.getName());
						bw.newLine();

						bw.flush();
						sleep(1000L + (long) (1000L * Math.random()));

						semaphore.release();
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		}.start();
	}

	private void initSocket(String hostname, int port) throws Exception {
		socket = new Socket(hostname, port);
		bw = new BufferedWriter(
				new OutputStreamWriter(socket.getOutputStream()));
	}

	private void startServer(final int port) {
		new Thread() {
			public void run() {
				try {
					System.out.println("starting server @ " + port);
					ServerSocket ss = new ServerSocket(port);
					socket = ss.accept();

					System.out.println("connected");

					BufferedReader br = new BufferedReader(
							new InputStreamReader(socket.getInputStream()));

					String line = null;
					while ((line = br.readLine()) != null) {
						System.out.print("received: ");
						System.out.println(line);
					}

					br.close();

				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}.start();
	}

}
```

Gruß Tom


----------



## knopper (17. März 2005)

Hi,
  Danke für die Ratschläge !

 Ich bekomme die Fehlermeldung :

 SocketSynchronizer.java:9: package java.util.concurrent does not exist

 Welche Java Version ist das ? 

 Gruss


----------



## Thomas Darimont (17. März 2005)

Hallo!

Wie ich schon schrieb verwende ich Java 5 genauer gesagt 


> C:\>java -version
> java version "1.5.0_02"
> Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_02-b09)
> Java HotSpot(TM) Client VM (build 1.5.0_02-b09, mixed mode, sharing)



Gruß Tom


----------



## knopper (17. März 2005)

*Danke Thomas,

 Ich habe bis jetzt noch nicht mit Semaphoren programmiert. Für Java 1.4 muss ich selber eine Semaphore Klasse definieren oder ?

 Gruss
*


----------



## Thomas Darimont (17. März 2005)

Hallo!

Nicht unbedingt ... das in Java 5 concurrent package basiert auf der Conncurent Library von Doug Lea...
http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html

Damit kannst du also "genauso" unter 1.4 entwickelen wie mit dem concurrent Package unter Java 5.

Gruß Tom


----------



## knopper (17. März 2005)

Es scheint  zu funktionieren.
  Ich habe den Code ein bisschen umgeschrieben:

```
import java.io.BufferedReader;
  import java.io.BufferedWriter;
  import java.io.IOException;
  import java.io.InputStreamReader;
  
  import java.io.BufferedInputStream;
  import java.io.InputStream;
  import java.io.OutputStream;
  import java.io.OutputStreamWriter;
  
  
  import java.net.ServerSocket;
  import java.net.Socket;
  import java.util.concurrent.Semaphore;
  
  /**
   * @author Administrator
   *
   */
  public class SocketSynchronizer {
  
  	private Socket socket;
  
  	private Semaphore semaphore = new Semaphore(1);
  
  	private BufferedWriter bw;
  	
  		private OutputStreamWriter sockout = null;
  		
  		private BufferedInputStream sockin = null;
  
  	/**
  	 * @param args
  	 */
  	public static void main(String[] args) throws Exception {
  		new SocketSynchronizer().start();
  	}
  
  	private void start() throws Exception {
  
  		Runtime.getRuntime().addShutdownHook(new Thread() {
  			public void run() {
 				System.out.println("Shuting down...");
  				try {
 					if (bw != null) {
 						bw.close();
  					}
 					if (socket != null) {
 			 		 socket.close();
  					}
  				} catch (IOException e) {
 					e.printStackTrace();
  				}
  			}
  		});
  
  		initSocket("localhost", 7777);
  
  		System.out.println(startClient("command1"));
  		System.out.println(startClient("command2"));
  
  
  	}
  
  	private void startClient(String name) {
  
  				new Thread(name) {
  			public void run() {
  				while (true) {
  					try {
 			 		 semaphore.acquire();
  
 												 try {
 													 sockout.write(this.getName());
 													 sockout.flush();
 												 }
 												 catch (Exception e) {
 													 e.printStackTrace();
 												 }
 													 String str = "";
 													 try {
 													 byte[] bline = new byte[6048];
 													 sockin.read(bline);
 													 str = new String(bline);
 												 }
 												 catch (Exception e) {
 													 e.printStackTrace();
 												 }
  
 									 	sleep(1000L + (long) (1000L * Math.random()));
  
 			 		 semaphore.release();
 					} catch (Exception e) {
 			 		 e.printStackTrace();
  					}
  				}
  			}
  		}.start();
  	}
  
  	private void initSocket(String hostname, int port) throws Exception {
  		socket = new Socket(hostname, port);
  	//	bw = new BufferedWriter(
 	//			new OutputStreamWriter(socket.getOutputStream()));
  
  		InputStream ISsockin = socket.getInputStream();
  		  OutputStream OSsockout = socket.getOutputStream();
  
  		  sockin = new BufferedInputStream(ISsockin);
  
  		  sockout = new OutputStreamWriter(OSsockout);
  	}
  
  }
```
 
  Nun wie kann ich str als Ruckgabewert zurückliefern ?

  Gruss


----------



## knopper (24. März 2005)

```
private void startClient(String name) {
  		String str = "";
  		new Thread(name) {
  			String str = "";
  			public void run() {
  				while (true) {
  					try {
  		    		    semaphore.acquire();
 						try {
 		 		 	sockout.write(this.getName());
 		 		 	sockout.flush();
 		 			} catch (Exception e) {
 		 		 	e.printStackTrace();
 						}
 		 			String str = "";
 						try {
 		 		 	byte[] bline = new byte[6048];
 		 		 	sockin.read(bline);
 		 		 	str = new String(bline); // soll sofort wieder geben
 		 			} catch (Exception e) {
 		 		 	e.printStackTrace();
 						}
  
 		 			sleep(1000L + (long) (1000L * Math.random()));
  
  		    		    semaphore.release();
 					} catch (Exception e) {
  		    		    e.printStackTrace();
  					}
  				}
  			}
  		}.start();
  	}
```
 
    Was ich machen wollte ist die Methode startClient mit einem String als Rückgabewert(new String(bline) umzuschreiben.
    Der Thread ist aber eine eigene Klasse. Wie kann ich dieses Problem umgehen.

     System.out.println(startClient("socket_command"));

    gruss


----------

