我打算解釋TCP:
基本概念是,你必須在機器上運行「服務器」。該服務器接受等待連接的客戶端。每個連接都通過一個端口(你知道,我希望...)。
始終使用端口1024以上的,因爲端口比1025低最的標準協議保留的時間(如HTTP(80),FTP(21),遠程登錄,...)
但是,創建Java中的一個服務器這樣做:
ServerSocket server = new ServerSocket(8888); // 8888 is the port the server will listen on.
「套接字」是你可能尋找的詞,如果你想做研究。
和你的客戶端連接到你有寫這個服務器:
Socket connectionToTheServer = new Socket("localhost", 8888); // First param: server-address, Second: the port
但現在,還沒有還存在連接。服務器必須接受等待的客戶端(正如我在上面注意到的那樣):
Socket connectionToTheClient = server.accept();
完成!您的連接已建立!通信就像File-IO一樣。你唯一要記住的是你必須決定什麼時候刷新緩衝區並真正通過套接字發送數據。
使用文本寫作一個PrintStream是非常方便的:
OutputStream out = yourSocketHere.getOutputStream();
PrintStream ps = new PrintStream(out, true); // Second param: auto-flush on write = true
ps.println("Hello, Other side of the connection!");
// Now, you don't have to flush it, because of the auto-flush flag we turned on.
一個BufferedReader文本閱讀是良好的(最好的*)選項:
InputStream in = yourSocketHere.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line = br.readLine();
System.out.println(line); // Prints "Hello, Other side of the connection!", in this example (if this would be the other side of the connection.
希望你可以用這個網絡開始信息!
PS:當然,所有網絡代碼都必須嘗試處理IOException。
編輯:我忘了寫它爲什麼不總是最好的選擇。 BufferedReader使用緩衝區並儘可能多地讀取緩衝區。但有時你不希望BufferedReader在換行符後面竊取字節並將它們放入自己的緩衝區中。
簡單的例子:
InputStream in = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
// The other side says hello:
String text = br.readLine();
// For whatever reason, you want to read one single byte from the stream,
// That single byte, just after the newline:
byte b = (byte) in.read();
但BufferedReader中早已是字節,你想讀的,在他的緩衝。因此調用in.read()
將返回讀取器緩衝區中最後一個字節的後續字節。
因此,在這種情況下,最好的解決方案是使用DataInputStream
並以自己的方式管理它,以知道字符串將會多長時間,並只讀取該字節數並將它們轉換爲字符串。或者:您可以使用
DataInputStream.readLine()
這種方法不使用緩衝區和字節,並檢查一個換行符讀取字節。所以這個方法不會竊取底層InputStream的字節。
編輯:您可以開發自己的協議,您可以在其中使用Java Reflexion請求方法調用。例如:
String className = ...;
String methodName = ...;
Class[] methodParamTypes = ...;
Object[] methodParams = ...;
Class cl = Class.forName(className);
Method me = cl.getDelcaredMethod(methodName, methodParamTypes);
Object returnValue = me.invoke(this, methodParams);
一旦你有你的對象,你可以把它送到與序列化連接的另一面:ObjectOuputStreams
和ObjectInputStreams
。通過這兩個類,您可以通過流寫入和讀取對象。
Object obj = ...; // Your object you want to write through the stream. (Needs to implement java.io.Serializable)
ObjectOutputStream oos = new ObjectOuptputStream(socket.getOutputStream());
oos.writeObject(oos);
oos.reset(); // (***)
// Don't close it! Otherwise the connection will be closed as well.
而且在連接的另一端:
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
Object object = ois.readObject(); // Read the object
// Don't close it!
// Then cast it to whatever you want.
(***)
:退房my question之進一步資料reset()
以及何時使用它。
我打算建議嘗試JMS生產者/消費者方法,但你想要一些簡單的東西。 – 2011-01-06 14:38:39