카테고리 없음

소켓 프로그래밍

미 누 리 2022. 5. 2. 22:56

1. 소켓 프로그래밍 : 대소문자 변환

  • 클라이언트에서 서버에 문자열을 보내면 서버에서는 그 문자열의 대소문자를 변환해 클라이언트에게 보내주는 프로그램

<server1.java>

package socket_programming;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

public class server1 {
    public static void main(String[] args) {
        ServerSocket server = null;
        Socket socket = null;
        BufferedReader brIn = null;
        BufferedWriter brOut = null;
        Scanner sc = new Scanner(System.in); // inputString으로 읽어올 것

        try {
            server = new ServerSocket(9999); // 정상적으로 열리면 9999로 열릴텐데 없다면 죽을 것
            System.out.println("연결 대기중...");

            socket = server.accept(); // accept() 리턴타입 : socket
            System.out.println("연결 되었습니다.");

            // 읽어올 준비
            brIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            // 쓸 준비
            brOut = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

            while(true) {
                String inMsg = brIn.readLine(); // brIn 으로부터 한 줄을 읽어와
                if(inMsg.equalsIgnoreCase("close")) { // 종료 메세지를 받으면 종료
                    System.out.println("클라이언트가 나갔습니다.");
                    break;
                }

                // 종료 메시지가 아니라 다른 일반 메세지라면

                // 클라이언트가 보낸 메시지 출력
                System.out.print("클라이언트 : " + inMsg);

                // 클라이언트로부터 받은 메세지의 대소문자를 변경
                int tmp;
                String outMsg = "";

                for(int i = 0; i < inMsg.length(); i++) {
                    tmp = (int)inMsg.charAt(i);
                    if((65 <= tmp) && (tmp <= 90)) { // 대문자인 경우
                        outMsg += (char)(tmp + 32);
                    }
                    else if((97 <= tmp) && (tmp <= 122)) {  // 소문자인 경우
                        outMsg += (char)(tmp - 32);
                    }
                    else {  // 다른 문자인 경우
                        outMsg += (char)tmp;
                    }
                }

                brOut.write(outMsg + "\n");
                brOut.flush(); // brOut가 버퍼로 되어 있어서 flush()로 밀어줘야 한다.
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally { // 앞에서 열어놓은 애들 닫아줌. 잘못되어도 닫아줘야 된다.
            try {
                sc.close();
                brOut.close();
                brIn.close();
                socket.close();
                server.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

 

<client1.java>

package socket_programming;

import java.io.*;
import java.net.Socket;
import java.util.Scanner;

public class client1 {
    public static void main(String[] args) {
        Socket socket = null;
        BufferedReader brIn = null;
        BufferedWriter brOut = null;
        Scanner sc = new Scanner(System.in); // inputString으로 읽어올 것

        try {
            socket = new Socket("localhost", 9999);

            // 읽어올 준비
            brIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            // 쓸 준비
            brOut = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

            while(true) {
                // 출력 메시지 준비
                System.out.print("보내기 >> ");
                String outMsg = sc.nextLine(); // 공백 가능

                if(outMsg.equalsIgnoreCase("close")) { // output 메세지를 만들었는데 그게 close라면
                    brOut.write(outMsg + "\n");
                    brOut.flush();
                    break;
                }

                // // 종료 메시지가 아니라 다른 일반 메세지라면
                brOut.write(outMsg + "\n");
                brOut.flush(); // brOut가 버퍼로 되어 있어서 flush()로 밀어줘야 한다

                String inMsg = brIn.readLine(); // brIn 으로부터 한 줄을 읽어와
                System.out.println("서버 >> " + inMsg); // 화면에 서버가 보낸 메세지가 뜸
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally { // 앞에서 열어놓은 애들 닫아줌. 잘못되도 닫아줘야 된다.
            try {
                sc.close();
                brOut.close();
                brIn.close();
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
  1. 아스키 코드를 이용해서 클라이언트에서 보낸 문자열의 대소문자를 변환해 반환한다.
  2. close로 종료

<결과>


2. 소켓 프로그래밍 : 아이디/ 패스워드 확인 

<server2.java>

package socket_programming;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Scanner;
import java.util.StringTokenizer;

public class server2 {
    public static void main(String[] args) {
        ServerSocket server = null;
        Socket socket = null;
        BufferedReader brIn = null;
        BufferedWriter brOut = null;
        Scanner sc = new Scanner(System.in); // inputString으로 읽어올 것
        StringTokenizer token = null;
        HashMap<String, String> map = new HashMap<>();

        // 예시를 위해 값 미리 추가
        map.put("apple", "0000");
        map.put("banana", "0001");

        try {
            server = new ServerSocket(9998); // 정상적으로 열리면 9999로 열릴텐데 없다면 죽을 것
            System.out.println("연결 대기중...");

            socket = server.accept(); // accept() 리턴타입 : socket
            System.out.println("연결 되었습니다.");

            // 읽어올 준비
            brIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            // 쓸 준비
            brOut = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            // 읽어온 것 토큰으로 나눌 준비

            while(true) {
                String inMsg = brIn.readLine(); // brIn 으로부터 한 줄을 읽어와
                token = new StringTokenizer(inMsg);

                if(inMsg.equalsIgnoreCase("close")) { // 종료 메세지를 받으면 종료
                    System.out.println("클라이언트가 나갔습니다.");
                    break;
                }

                // 종료 메시지가 아니라 다른 일반 메세지라면

                // 클라이언트가 보낸 메시지 출력
                System.out.println("클라이언트 : " + inMsg);

                // 패스워드와 아이디
                String id = token.nextToken();
                String pwd = token.nextToken();
                String outMsg = "";

                if(map.get(id) == null || !map.get(id).equals(pwd)){ // 아이디가 없거나 비밀번호가 틀리면 새로운 회원이라고 가정
                    map.put(id, pwd);
                    brOut.write("회원등록 되셨습니다." + "\n");
                    brOut.flush(); // brOut가 버퍼로 되어 있어서 flush()로 밀어줘야 한다.
                }
                else if(map.get(id).equals(pwd)) {
                    brOut.write("환영합니다." + id + "님" + "\n");
                    brOut.flush(); // brOut가 버퍼로 되어 있어서 flush()로 밀어줘야 한다.
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally { // 앞에서 열어놓은 애들 닫아줌. 잘못되도 닫아줘야 됌
            try {
                sc.close();
                brOut.close();
                brIn.close();
                socket.close();
                server.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

 

<client2.java>

package socket_programming;

import java.io.*;
import java.net.Socket;
import java.util.Scanner;

public class client2 {
    public static void main(String[] args) {
        Socket socket = null;
        BufferedReader brIn = null;
        BufferedWriter brOut = null;
        Scanner sc = new Scanner(System.in); // inputString으로 읽어올 것

        try {
            socket = new Socket("localhost", 9998);

            // 읽어올 준비
            brIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            // 쓸 준비
            brOut = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

            while(true) {
                // 출력 메시지 준비
                System.out.print("보내기 >> ");
                String outMsg = sc.nextLine(); // 공백 가능

                if(outMsg.equalsIgnoreCase("close")) { // output 메세지를 만들었는데 그게 close라면
                    brOut.write(outMsg + "\n");
                    brOut.flush();
                    break;
                }

                // // 종료 메시지가 아니라 다른 일반 메세지라면
                brOut.write(outMsg + "\n");
                brOut.flush(); // brOut가 버퍼로 되어 있어서 flush()로 밀어줘야 한다

                String inMsg = brIn.readLine(); // brIn 으로부터 한 줄을 읽어와
                System.out.println("서버 >> " + inMsg); // 화면에 서버가 보낸 메세지가 뜸
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally { // 앞에서 열어놓은 애들 닫아줌. 잘못되도 닫아줘야 됌
            try {
                sc.close();
                brOut.close();
                brIn.close();
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
  1. stringTokenizer를 사용해서 client가 보낸 메세지를 공백을 기준으로 끊어준다. (클라이언트의 입력은 "아이디 패스워드" 라고 가정.
  2. 끊어진 문자열은 각각 아이디/ 패스워드를 의미한다. 
  3. 이 문자열을 서버가 가지고 있는 HashMap에서 찾고 비교하면서 있다면 "환영합니다", 없다면 HashMap에 값을 추가
  4. 신규 회원일 때 get(id)를 했을 경우,  null이 반환되므로 null인지 조건을 확인하는 부분이 조건문 중 가장 앞에 와야 했다. 그렇게 하지 않으면 get(id)가 null값을 반환한다고 에러 메세지가 뜬다.
  5. "close" 입력으로 종료

 

<결과>