2011-01-06 9 views
9

クライアント/サーバーの方法でJavaアプリケーションを作成しようとしています。 クライアントは、サーバーからのデータを表示するSWTのGUIです。サーバーはデータベースに接続されています。クライアントサーバーのJavaアプリケーションを作成する

申し訳ありませんが、これは古典的な質問ですが、どうやって起動するのか分かりません。

私が働いてくれたプロジェクトでは、Proxy.newProxyInstance()で多くの魔法を実装してGlassfishサーバーを透過的に起動しました。

私はGlassfishサーバーを使いたくありません。私は単純なJavaで単純なものをほしいだけです。しかし、プロキシの概念はかなりクールだ。

このようなことのアイデアや例がありますか?クライアントの要求を処理するためにサーバー部分を記述するにはどうすればよいですか?事前に

おかげ

Fluminis

+0

私はJMSプロデューサ/コンシューマアプローチを試してみることを提案していましたが、 –

答えて

34

私はTCPを説明するつもりです:
基本的なコンセプトは、マシン上で "サーバー"を実行する必要があるということです。そのサーバーは、接続を待っているクライアントを受け入れます。それぞれの接続はポートを経由します(わかります、私は...)。
1025より小さいポートは、HTTP(80)、FTP(21)、Telnetなどの標準プロトコル用に予約されているため、常に1024を超えるポートを使用してください。

ただし、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. 

A 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()

このメソッドは、バッファを使用せず、1バイトずつ読み込み、改行をチェックします。そのため、このメソッドは、基礎となるInputStreamからバイトを盗み出しません。


EDIT:Java Reflexionを使用してメソッド呼び出しをリクエストできる独自のプロトコルを開発できます。たとえば:ObjectOuputStreamsObjectInputStreams:あなたのオブジェクトを持っていたら

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); 

あなたはシリアル化との接続の反対側にそれを送ることができます。これらの2つのクラスを使用すると、ストリームを通じてオブジェクトを書き込みおよび読み込むことができます。

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. 

(***)reset()とするとき、それを使用する方法の詳細についてはmy questionをチェックしてください。

+0

あなたの答えをありがとう。テキストを検索する方法の例をよく理解しています。しかし、soketを使用してサーバー上でメソッドを呼び出し、複雑なオブジェクトを取得することは可能でしょうか? – fluminis

+0

ObjectOutputStreamとObjectInputStreamを見てください。 –

+1

また、あなたはJava RMI(リモートメソッド呼び出し)について考えているかもしれません - それに関する良い文書があります。 –

3

あなたは、単純なクライアント・サーバ型のプログラムを作成したい場合は、このtutorialで与えられたアドバイスに従うことができます。

もう少し複雑なことをしたいのなら、普通のJavaでは、あなたはRMIを見る必要があるでしょう。

しかし、今日では、web servicesはすべての怒りであり、長期的にはそれはより簡単であることがわかります。

1
  1. あなたはコミュニケーション/メッセージングプロトコルに決める(loadThing、editThing、makeThingBelch)
  2. を提供したいサービスを特定します(httpはstraightfowardようです。)
  3. 必ず彼らを動作させるために頻繁に、ユニットテストをサービスを実現。
  4. クライアントの作成を開始しました。新しいサービスを追加したり、既存のサービスを変更する必要があることに注意してください。

既存のアプリケーションサーバーを使用するのではなく、「シンプルなJava」で記述する理由は何ですか?通信、セキュリティ、トランザクションの整合性などを抽象化して管理するためのEJB3のいくつかのこと?

5

グラスフィッシュは必要以上の火力になるかもしれませんが、私は既存のライブラリを活用することを諦めません。ソケット用

いくつかのオプション:

ソケットよりもWebサービスに向ける場合、Jettyは小さなフットプリントHTTPを使用する方法です。

関連する問題