네트워크2

제이·2023년 3월 21일
0

네트워크

목록 보기
2/2
post-thumbnail

어제는 1:1
복수의 클라이언트가 접속하려고 한다면?

클라이언트가 접속을 하려면 서버는 accept()라는 기능을 수행하고 있어야 한다. 서버입장에서는 클라이언트를 나타내는 소켓이 필요한데 그걸 accept()가 생성해준다?
근데 이거 accept를 딱 한번만 해줘서 한번만 연결됨.

1.언제 접속할지 모른다.
-> 계속 s.accept()를 시킨다.(반복)
이 결과로 소켓을 얻어야지 접속한다.
accept() : 접속대기 -> 소켓얻기
=> main이 할 일

2.통신하기(클라이언트가 언제 프린트ln할 지 모른다)
=> 클라이언트가 접속할 때마다 thread를 생성

=>클라이언트가 접속할 때마다 thread가 늘어난다. 그래서 클라이언트가 2개이면 thread는 3개가 된다. (1개는 accept(), 2개는 클라이언트 각 하나씩.)

위의 두가지가 일어난다.
두개가 별개로 반복문을 해야한다.
readline에서 대기하고 accept에서 대기하고.


클라이언트가 접속하려고 할 때, 가능하게 해주는 것이 서버소켓의 accept()다. 클라이언트가 여러개 해주려고 한다면, accept()가 여러개 있어야 한다. 근데 언제든지 클라이언트가 올 수 있게 해주려면 무한대기 하고 있어야 한다.
accept의 결과로 소켓이 나옴. 그리고 동시에 연결해야하니까. 만약 스레드를 하지 않으면, 글을 주고 받고 있을 때 받아들이지 못하니까 스레드를 적어야 줘야 한다. 그리고 언제 글이 올지 모르니까 readline()도 무한대기, 무한반복 해줘야 한다. 스레드들은 하나씩 만든다.

MyUtil

public class MyUtil {
	public static void closeAll(Closeable... c) {
		for(Closeable temp : c) {
			try {
				temp.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

Client

public class Client {
	public static void main(String[] args) {
		Socket sock = null;
		
		OutputStream os = null;
		OutputStreamWriter osw = null;
		PrintWriter pw = null;
		
		InputStream is = null;
		InputStreamReader isr = null;
		BufferedReader br = null;
		
		InputStreamReader keyIsr = null;
		BufferedReader keyboard = null;
		
		try { 
			sock = new Socket("127.0.0.1", 10001);
			
			os = sock.getOutputStream();
			is = sock.getInputStream();
			
			osw = new OutputStreamWriter(os);
			pw = new PrintWriter(osw);
			
			isr = new InputStreamReader(is);
			br = new BufferedReader(isr);
			
			keyIsr = new InputStreamReader(System.in);
			keyboard = new BufferedReader(keyIsr);
			
			String line = null;
			while((line =keyboard.readLine())!= null) {
				if(line.equals("quit")) break;
				pw.println(line);
				pw.flush();
				System.out.println(br.readLine());
			}
			
			System.out.println(line);
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			MyUtil.closeAll(keyboard,keyIsr,br,isr,is,pw,osw,os,sock);
		}
        //소켓을 무조건 닫아줘라. 맨마지막에!
	}
}

Server(Thread가 분리된)

class Thread12 extends Thread {
	Socket sock;
	public Thread12(Socket sock) {
		this.sock = sock;
	}
	public void run() {
		OutputStream os = null;
		OutputStreamWriter osw = null;
		PrintWriter pw = null;
		
		InputStream is = null;
		InputStreamReader isr = null;
		BufferedReader br = null;
		
		try {
			os = sock.getOutputStream();
			is = sock.getInputStream();
			
			osw = new OutputStreamWriter(os);
			pw = new PrintWriter(osw);
			
			isr = new InputStreamReader(is);
			br = new BufferedReader(isr);
			
			String line = null;
			while((line = br.readLine()) != null) {
				System.out.println(line);
				pw.println(line);
				pw.flush();
			}
			System.out.println(line);
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			MyUtil.closeAll(pw,osw,os,br,isr,is,sock);
		}
	}
	
}

public class Server {
	public static void main(String[] args) {
		Socket sock = null;
		try {
			ServerSocket server = new ServerSocket(10001);
			
			while(true) {
				sock = server.accept();
				InetAddress inetaddr = sock.getInetAddress();
				System.out.println(inetaddr.getHostAddress() + "이 접속했다.");
                //특별한 이유없이 계속 반복하겠다는 무한반복문.
				//언제 접속할지 모르기 때문에 이렇게 해놨다. 
				//얘는 걍 접속만 하는 거
				Thread12 th = new Thread12(sock);
                //실제통신하는 건 Thread12가 한다.
				th.start();
			}			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}


(퍼온 사진)


채팅

t1이 c1이 한 말을 c2에게 보낸다면?
c1이 말한 걸 c2가 볼 수 있게 된다. 이럼 채팅이 된다.
c1이 t1한테도 보내고, c2한테도 보낸다.
c2가 t2한테도 보내고, t2가 c1한테 보낸다면? 그게 채팅.

profile
Hello :)

0개의 댓글