待ち受けるサーバーは、アクセスがあるとソケットをそのままKitayo06に渡します。
Kitayo06はそのソケットを使ってストリームを得て相手からメッセージを読み、表示をしたらソケットを閉じます。
Kitayo06に用意された返信ボタンによりClient06が起動します。Client06は返信相手のホスト名だけを受け継ぎます。返信文を入力してボタンをクリックした後に改めて返信先と接続を作って送信します。
またClient06はServer06からも起動されますが、この時はホスト名は起動してから入力されるようにします。
Server06 受信待機と送信ボタンの受付 |
||
クライアントから のアクセス ↓ |
ボタンのクリック ↓ |
|
Kitayo06 受信と表示 |
ボタンの クリック → |
Client06 送信のみ |
使う時には、Server06からスタートします。今の所Client06は個別に起動できません。
いままでサーバーを起動したままクライアントを起動して自分のホストで動作テストをしていましたが、サーバーを2つ同時に立てられませんから(PORTが同じなので)、テストは1つのサーバーからクライアントを起動して自分に送信して行います。
このサーバーも 10001 ポートで待ちます。このポート番号はここだけで指定します。
/** サーバー、クライアントの統合 */ import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; public class Server06 extends JFrame implements ActionListener { ServerSocket mysvsoc; Socket mysoc; int PORT = 10001; JButton sndbttn; JButton endbttn; public Server06() { setTitle("Server06 "+Thread.currentThread().getName()); setDefaultCloseOperation(EXIT_ON_CLOSE); sndbttn = new JButton("送信"); endbttn = new JButton("終了"); setLayout(new BorderLayout()); add(sndbttn, BorderLayout.CENTER); add(endbttn, BorderLayout.EAST); sndbttn.addActionListener(this); endbttn.addActionListener(this); pack(); setVisible(true); try { mysvsoc = new ServerSocket( PORT ); while( true ) { System.out.println( "受信のため待機中..." ); Socket mysoc = mysvsoc.accept(); //受信待ち String remotehost = mysoc.getInetAddress().getHostName(); System.out.println("from " + remotehost); // 処理をKitayo06に任せますnew Kitayo06(mysoc);Kitayo06 kitayo = new Kitayo06(mysoc); kitayo.setLocationRelativeTo(this); } } catch( IOException e ) { System.err.println("IO Error"); } } public void actionPerformed(ActionEvent ev) { if (ev.getSource() == sndbttn) { System.out.println("Client06 " + PORT); Client06 cl = new Client06( "" , PORT); cl.setLocationRelativeTo(this); } if (ev.getSource() == endbttn) { try{ if (mysoc == null) mysoc = new Socket( "127.0.0.1", PORT ); mysoc.close(); mysvsoc.close(); System.exit(0); } catch( IOException ex ){ System.err.println("IO Error in action"); } } } public static void main( String[] args ) { Server06 sv = new Server06(); } }
起動するとこのようなウインドウが開きます。
このサーバーはひとつのホストに一つだけ起動できます。2つ起動するとポートの取り合いになり動作がおかしくなります。
通信相手のホストでも同じサーバーを起動して通信することを想定しています。
/** GUIで受信を知らせる */ import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; public class Kitayo06 extends JFrame implements ActionListener { String remotehost; Socket mysoc; JButton sndbttn; int PORT; public Kitayo06(Socket soc) { mysoc = soc; setTitle("Kitayo06 "+Thread.currentThread().getName()); setDefaultCloseOperation(DISPOSE_ON_CLOSE); //[×]ボタン処理 JLabel aite = new JLabel("相手機: "+mysoc.getInetAddress().getHostName()); JLabel rcvmsg = new JLabel("受信文: "); sndbttn = new JButton("返信"); sndbttn.addActionListener(this); PORT = mysoc.getLocalPort(); remotehost = mysoc.getInetAddress().getHostName(); setLayout(new GridLayout(3,1,0,0)); add(aite); add(rcvmsg); add(sndbttn); Dimension ps = rcvmsg.getPreferredSize(); ps.width = 224; rcvmsg.setPreferredSize(ps); try{ InputStreamReader in = new InputStreamReader(mysoc.getInputStream()); BufferedReader inb = new BufferedReader(in); String line; line = inb.readLine(); rcvmsg.setText("受信文: "+line); inb.close(); in.close(); mysoc.close(); } catch( IOException e ) { System.err.println("IO Error"); } pack(); setVisible(true); } public void actionPerformed(ActionEvent ev) { if (ev.getSource() == sndbttn) { Client06 cl = new Client06( remotehost , PORT); cl.setLocationRelativeTo(this); dispose(); //自分は消える } } }
次のようなウインドウで通信文を示し、返信ボタンを押すと送信クライアントを起動します。
/** GUIで送信するクライアント */ import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; public class Client06 extends JFrame implements ActionListener { JTextField aite; JTextField sndmsg; JButton sndbttn; Socket mysoc; int PORT; public Client06(String host,int p) { setTitle("Client06 "+Thread.currentThread().getName()); setDefaultCloseOperation(DISPOSE_ON_CLOSE); PORT = p; String bttntext = "送信"; if (host!="") bttntext = "返信"; aite = new JTextField(host); sndmsg = new JTextField(20); sndbttn = new JButton(bttntext); setLayout(new GridLayout(3,1,0,0)); add(aite); add(sndmsg); add(sndbttn); sndbttn.addActionListener(this); pack(); setVisible(true); if (host!="") sndmsg.requestFocusInWindow(); } public void actionPerformed(ActionEvent ev) { if (ev.getSource() == sndbttn) { try{ mysoc = new Socket( aite.getText(), PORT ); System.out.println( aite.getText() + " " + PORT); OutputStreamWriter out = new OutputStreamWriter(mysoc.getOutputStream()); BufferedWriter outb = new BufferedWriter(out); String msg = sndmsg.getText(); outb.write( msg ); outb.newLine(); outb.close(); out.close(); mysoc.close(); } catch( UnknownHostException ex ) { System.err.println( "Host not found" ); } catch( IOException ex ) { System.err.println("IO Error in action"); } dispose(); } } }
Kitayo06から呼び出されると次のようになります。
返事の文を書いて返信ボタンを押せば相手と接続して送信し、自らは消えます。
一方、Server06から送信ボタンを押せば、相手のホスト名が空白のままClient06が起動します。
今でどおり、相手のホスト名と通信文を入れて送信すると、自らは消えます。