サーバー、クライアントの統合

機能の見直しと統合

Server06
受信待機と送信ボタンの受付
クライアントから
のアクセス
ボタンのクリック
Kitayo06
受信と表示
ボタンの
クリック
Client06
送信のみ

このクライアントはまだまだ欠陥がありますが、動きます。どこに問題があるかわかるでしょうか。

どんな改良をすれば便利になるでしょうか。

使う時には、Server06からスタートします。Client06は個別に起動できません。

サーバー

このサーバーも 10001 ポートで待ちます。このポート番号はここだけで指定します。

プログラム名 Server06.java

/** 受信後返信ウィンドウを呼び出すサーバー */
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;
    int PORT = 10001;
    JButton sndbttn;

    public Server06() {
        //[×]ボタンを押した時の処理
        addWindowListener(new WindowAdapter(){
            public void windowClosing(WindowEvent we){
                terminate();
            }
        });
        //ただ1つのボタンを配置
        sndbttn = new JButton("送信");
        setLayout(new BorderLayout());
        add(sndbttn, BorderLayout.CENTER);
        
        sndbttn.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);
            }
        }
        catch( SocketException e ) {
            System.err.println("Socket Error");
        }
        catch( IOException e ) {
            System.err.println("IO Error");
        }
    }
    public void actionPerformed(ActionEvent ev) {
        if (ev.getSource() == sndbttn) {
            System.out.println("Client06 " + PORT);
            new Client06( "" , PORT);
        }
    }
    public void terminate(){
        try{
            System.out.println(mysvsoc.isClosed() );
            mysvsoc.close();
            System.exit(0);
         }
         catch( Exception e ){
            System.out.println(e.toString());
         }
    }
    public static void main( String[] args ) {
         Server06 sv = new  Server06();
    }
}

委託されるGUIプログラム

プログラム名 Kitayo06.java

/** GUIで送信するクライアント */
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
public class Kitayo06 extends JFrame implements ActionListener {
    JButton sndbttn;
    JTextField rcvmsg;
    String remotehost;
    Socket mysoc;
    int PORT;
    public Kitayo06(Socket soc) {
        mysoc = soc;
        PORT = mysoc.getLocalPort();
        setDefaultCloseOperation(DISPOSE_ON_CLOSE); //[×]ボタン処理
        remotehost = mysoc.getInetAddress().getHostName();
        JLabel hostlabel = new JLabel(remotehost);
        rcvmsg   = new JTextField();
        sndbttn  = new JButton("返信");
        setLayout(new BorderLayout());
        add(hostlabel,BorderLayout.NORTH);
        add(rcvmsg,  BorderLayout.CENTER);
        add(sndbttn, BorderLayout.SOUTH);
        
        sndbttn.addActionListener(this);
        
        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( SocketException e ) {
            System.err.println("Socket Error in message");
        }
        catch( IOException e ) {
            System.err.println("IO Error");
        }
        catch( Exception e ){
            System.out.println(e.toString());
        }
        pack();
        setVisible(true);
    }
    public void actionPerformed(ActionEvent ev) {
        if (ev.getSource() == sndbttn) {
            new Client06(remotehost,PORT);
            dispose();  //自分は消える
        }
    }
}

クライアント

プログラム名 Client06.java

/** GUIで送信するクライアント */
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
public class Client06 extends JFrame implements ActionListener {
    JButton sndbttn;
    JTextField sndmsg;
    JTextField disthost;
    Socket mysoc;
    int PORT;
    public Client06(String s,int p) {
        PORT = p;
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        disthost = new JTextField(s);
        sndmsg   = new JTextField();
        sndbttn  = new JButton("送信");
        setLayout(new BorderLayout());
        add(disthost,BorderLayout.NORTH);
        add(sndmsg,  BorderLayout.CENTER);
        add(sndbttn, BorderLayout.SOUTH);
        
        sndbttn.addActionListener(this);
        
        pack();
        setVisible(true);
    }
    public void actionPerformed(ActionEvent ev) {
        if (ev.getSource() == sndbttn) {
            try{
                mysoc = new Socket( disthost.getText(), PORT );
                System.err.println(disthost.getText() + " " + PORT);
                OutputStreamWriter out
                  = new OutputStreamWriter(mysoc.getOutputStream());
                BufferedWriter outb = new BufferedWriter(out);
                String msg = sndmsg.getText();
                outb.write( msg, 0, msg.length() );
                outb.newLine();
                outb.close();
                out.close();
                mysoc.close();
            }
            catch( UnknownHostException e ) {
                System.err.println(disthost.getText() + " " + PORT);
                System.err.println( "Host not found" );
            }
            catch( SocketException e ) {
                System.err.println("Socket Error");
            }
            catch( IOException e ) {
                System.err.println("IO Error");
            }
            catch( Exception e ){
                System.out.println(e.toString());
            }
            dispose();
        }
    }
}

課題

ウィンドウの位置が重なって使いにくいです。乱数を使ってウインドウの位置を指定し、離して表示することはできるでしょうか。

位置をマイナスにしたり、画面からはみ出す設定になるとやっかいです。注意。

もくじ

聖愛高等学校
http://www.seiai.ed.jp/
Last Modified