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();
}
}
}
}
- 아스키 코드를 이용해서 클라이언트에서 보낸 문자열의 대소문자를 변환해 반환한다.
- 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();
}
}
}
}
- stringTokenizer를 사용해서 client가 보낸 메세지를 공백을 기준으로 끊어준다. (클라이언트의 입력은 "아이디 패스워드" 라고 가정.
- 끊어진 문자열은 각각 아이디/ 패스워드를 의미한다.
- 이 문자열을 서버가 가지고 있는 HashMap에서 찾고 비교하면서 있다면 "환영합니다", 없다면 HashMap에 값을 추가
- 신규 회원일 때 get(id)를 했을 경우, null이 반환되므로 null인지 조건을 확인하는 부분이 조건문 중 가장 앞에 와야 했다. 그렇게 하지 않으면 get(id)가 null값을 반환한다고 에러 메세지가 뜬다.
- "close" 입력으로 종료
<결과>