꾸준히 안타치기

TCPIP / 소켓예제 (구민사) 대화명: 채팅주고 받기 본문

Android _ 서버연동_채팅/Android - study

TCPIP / 소켓예제 (구민사) 대화명: 채팅주고 받기

글자줍기 2021. 12. 16. 10:44
반응형

인텔리제이에서

서버를 먼저 켜고, 클라이언트를 켠다.

로그온창에 아이디를 입력하고 엔터를 친다.

대화말에 대화내용을 친다.

클라이언트를 여러개 실행하려면, 클라측

코드를 복사해서 하나 더 실행시키니 되었다.

 

ChatMessageS.java (서버)

import javax.imageio.IIOException;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

public class ChatMessageS extends Frame {
    TextArea display;
    Label info;
    List<ServerThread> list;

    public ServerThread SThread;

    public ChatMessageS() {
        super("서버");
        info = new Label();
        add(info, BorderLayout.CENTER);
        display = new TextArea("", 0, 0, TextArea.SCROLLBARS_VERTICAL_ONLY);
        display.setEditable(false);
        add(display, BorderLayout.SOUTH);
        addWindowListener(new WinListener());
        setSize(300, 250);
        setVisible(true);
    }

    public void runServer() {
        ServerSocket server;
        Socket sock;
        ServerThread SThread;
        try {
            list = new ArrayList<ServerThread>();
            server = new ServerSocket(5003, 100);
            try {
                while (true) {
                    sock = server.accept();
                    SThread = new ServerThread(this, sock, display, info);
                    SThread.start();
                    info.setText(sock.getInetAddress().getHostName() + "서버는 클라이언트와 연결됨");
                }
            } catch (IOException ioe) {
                server.close();
                ioe.printStackTrace();
            }

        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }

    public static void main(String[] args) {
        ChatMessageS s = new ChatMessageS();
        s.runServer();
    }

    class WinListener extends WindowAdapter {
        public void windowClosing(WindowEvent e) {
            System.exit(0);
        }
    }
}

class ServerThread extends Thread {
    Socket sock;
    BufferedWriter output;
    BufferedReader input;
    TextArea display;
    Label info;
    TextField text;
    String clientdata;
    String serverdata = "";
    ChatMessageS cs;

    private static final String SEPARATOR = "|";
    private static final int REQ_LOGON = 1001;
    private static final int REQ_SENDWORDS = 1021;

    public ServerThread(ChatMessageS c, Socket s, TextArea ta, Label l) {
        sock = s;
        display = ta;
        info = l;
        cs = c;
        try {
            input = new BufferedReader(new InputStreamReader(sock.getInputStream()));
            output = new BufferedWriter(new OutputStreamWriter(sock.getOutputStream()));
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }

    public void run() {
        cs.list.add(this);
        try {
            while ((clientdata = input.readLine()) != null) {
                StringTokenizer st = new StringTokenizer(clientdata, SEPARATOR);
                int command = Integer.parseInt(st.nextToken());
                int cnt = cs.list.size();
                switch (command) {
                    case REQ_LOGON : { // 1001 아이디를 수신한 경우
                        String ID = st.nextToken();
                        display.append("클라이언트가" + ID + "(으)로 로그인 하였습니다.");
                        break;
                    }
                    case REQ_SENDWORDS : { // 1021 아이디 대화말을 수신
                        String ID = st.nextToken();
                        String message = st.nextToken();
                        display.append(ID + ":" + message + "\r\n");
                        for (int i = 0; i < cnt; i++) { // 모든 클라이언트에게 전송
                            ServerThread SThread = (ServerThread) cs.list.get(i);
                            SThread.output.write(ID + ":" + message + "\r\n");
                            SThread.output.flush();
                        }
                        break;
                    }
                }
            }
                } catch (IOException e) {
                    e.printStackTrace();
                }
                cs.list.remove(this);
                try {
                    sock.close();
                } catch (IOException ea) {
                    ea.printStackTrace();
                }
            }
}

 

ChatMessageC.java (클라이언트)

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

public class ChatMessageC extends Frame implements ActionListener, KeyListener {

    TextArea display;
    TextField wtext, ltext;
    Label mlbl, wlbl, loglbl;
    BufferedWriter output;
    BufferedReader input;
    Socket client;
    StringBuffer clientdata;
    String serverdata;
    String ID;

    private static final String SEPARATOR = "|";
    private static final int REQ_LOGON = 1001;
    private static final int REQ_SENDWORDS = 1021;

    public ChatMessageC() {
        super("클라이언트");

        mlbl = new Label("채팅 상태를 보여줍니다.");
        add(mlbl, BorderLayout.NORTH);

        display = new TextArea("", 0, 0, TextArea.SCROLLBARS_VERTICAL_ONLY);
        display.setEditable(false);
        add(display, BorderLayout.CENTER);

        Panel ptotal = new Panel(new BorderLayout());
        Panel pword = new Panel(new BorderLayout());
        wlbl = new Label("대화말");
        wtext = new TextField(30); // 전송할 데이터를 입력하는 필드
        wtext.addKeyListener(this);// 입력된 데이터를 송신하기 위한 이벤트 연결
        pword.add(wlbl, BorderLayout.WEST);
        pword.add(wtext, BorderLayout.EAST);
        ptotal.add(pword, BorderLayout.CENTER);

        Panel plabel = new Panel(new BorderLayout());
        loglbl = new Label("로그온");
        ltext = new TextField(30); // 전송할 데이터를 입력하는 필드
        ltext.addActionListener(this); // 입력된 데이터를 송신하기 위한 이벤트 연결
        plabel.add(loglbl, BorderLayout.WEST);
        plabel.add(ltext, BorderLayout.EAST);
        ptotal.add(plabel, BorderLayout.SOUTH);

        add(ptotal, BorderLayout.SOUTH);

        addWindowListener(new WinListener());
        setSize(300, 250);
        setVisible(true);
    }

    public void runClient() {
        try {
            client = new Socket(InetAddress.getLocalHost(), 5003);
            System.out.println(client +"접속 ip 주소");
//            client = new Socket(InetAddress.getLocalHost(), 5001);
            mlbl.setText("연결된 서버이름 :" + client.getInetAddress().getHostName());
            input = new BufferedReader(new InputStreamReader(client.getInputStream()));
            output = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
            clientdata = new StringBuffer(2048);
            mlbl.setText("접속완료 사용할 아이디를 입력하세요");
            while (true) {
                serverdata = input.readLine();
                display.append(serverdata + "\r\n");
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void actionPerformed(ActionEvent ae) {
        if (ID == null) {
            ID = ltext.getText();
            mlbl.setText(ID + "(으)로 로그인하였습니다.");

            try {
                clientdata.setLength(0);
                clientdata.append(REQ_LOGON);
                clientdata.append(SEPARATOR);
                clientdata.append(ID);
                output.write(clientdata.toString() + "\r\n");
                output.flush();
                ltext.setVisible(false);

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args){
        ChatMessageC c = new ChatMessageC();
        c.runClient();
    }

    class WinListener extends WindowAdapter{
        public void windowClosing(WindowEvent e){
            System.exit(0);
        }
    }

    public void keyPressed(KeyEvent ke){
        if(ke.getKeyChar() ==  KeyEvent.VK_ENTER){
            String message;
            message = wtext.getText();
            if(ID == null){
                mlbl.setText("다시 로그인 하세요!!!");
                wtext.setText("");
            }else{
                try{
                    clientdata.setLength(0);
                    clientdata.append(REQ_SENDWORDS);
                    clientdata.append(SEPARATOR);
                    clientdata.append(ID);
                    clientdata.append(SEPARATOR);
                    clientdata.append(message);
                    output.write(clientdata.toString() +"\r\n");
                    output.flush();
                    wtext.setText("");

                }catch (IOException e ){
                    e.printStackTrace();
                }
            }
        }
    }

    public void keyReleased(KeyEvent ke){
    }

    public void keyTyped(KeyEvent ke){

    }
}
반응형
Comments