어제는 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()도 무한대기, 무한반복 해줘야 한다. 스레드들은 하나씩 만든다.
public class MyUtil {
public static void closeAll(Closeable... c) {
for(Closeable temp : c) {
try {
temp.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
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);
}
//소켓을 무조건 닫아줘라. 맨마지막에!
}
}
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한테 보낸다면? 그게 채팅.