Daily coding
Thread 사용한 소켓 프로그래밍 예제 - client 본문
Client Class 및 Thread 작성하기
< 순서 >
1. 접속을 해야할 Server Ip(주소)를 설정 - Socket Adress
2. Socket 생성
3. 접속 connect
4. 통신
1. mainClass
- 서버와 연결할 소켓을 생성한다. 소켓에 들어갈 주소는 서버와 관련된 정보이다.
1. 연결할 서버의 IP주소
2. 연결할 서버의 Port
Socket 객체를 생성할 때 파라미터에 넣어 생성해도 괜찮고,
소켓 연결에 필요한 정보를 담을 InetSocketAddress 객체를 생성하여 입력하여도 좋다.
1. Socket socket = new Socket("000.000.000.000" , portNum) ;
---> 이 경우는 생성자의 파라미터에 서버 연결 IP와 port 가 있기 때문에 connect를 통해 연결하지 않아도 연결이 된다.
2. Socket socket = new Socket();
socket.connect("000.000.000.000" , portNum );
혹은
InetSocketAddress sockAddr = new InetSocketAddress("000.000.000.000", 9000 );
socket.connect(sockAddr,porNum);
----> 이 경우는 소켓이 연결될 주소 값이 비어있기 때문에
InetSocketAddress 객체를 생성하거나 connect 함수에 직접 주소와 포트 넘버를 써줘야 한다.
public class mainClass_Client {
// Client
public static void main(String[] args) {
// TODO Auto-generated method stub
/*
1. 접속을 해야할 Server Ip(주소)를 설정 - Socket
2. Socket 생성
3. 접속 connect
4. 통신
*/
InetSocketAddress sockAddr = new InetSocketAddress("192.168.2.31", 9000 );
// (IP주소, 포트넘버)
Socket socket = new Socket();
// 단 한개인 클라이언트 소켓
System.out.println("서버와 연결중...");
// Server에 접속
try {
socket.connect(sockAddr, 100000 );
// (문지기 소켓 객체, 만분의1초(현재는 10초임))
InetAddress inetAddr;
if((inetAddr = socket.getInetAddress())!= null) {
System.out.println("서버연결 성공 : " + inetAddr);
}else {
System.out.println("서버 연결 실패");
}
// 전송할 데이터 만들기
Scanner sc = new Scanner(System.in);
// 문자열 받아오는 스레드 만들기
new ReadThread(socket).start();
while(true) {
System.out.print(">> ");
String str = sc.next();
// thread 돌리기 위해서는 언제 받을지 모르는 Receive부터 쓴 뒤 send한다
// 1. send
PrintWriter writer = new PrintWriter(socket.getOutputStream());
// getOutputStream --> 내보낼 데이터
writer.println(str); // 실질적으로 전송이 되는 문자열
writer.flush(); // 끝맺음
- 서버와 클라이언트가 연결된 후에는 데이터를 입력받는 스레드부터 만든다.
- 접속한 다른 클라이언트로부터 언제 메세지를 받을 지 모르기 때문에 Receive 스레드부터 돌리는 것
* ReadThread
: ReadThread 클래스는 이렇게 구성된다.
- BufferedReader를 통해 클라이언트의 소켓의 InputStream에 들어간 데이터를 가져온다.
- readLine()을 통해 문자열로 데이터를 받아오고, 콘솔에 출력한다.
- Thread.sleep() 메소드는 스레드가 돌아가는 주기로, 단위는 밀리세컨즈.
300 정도로 맞추어 두는 것이 좋음
public class ReadThread extends Thread {
Socket socket;
public ReadThread(Socket socket) {
this.socket = socket;
}
// run 함수 오버라이딩
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
// receive : 받기
try {
while(true) {
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String str;
str = reader.readLine();
System.out.println("서버로부터 받은 메세지 : " + str);
Thread.sleep(300); // 시간은 맞춰놓는 것이 좋음
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
* 다시 mainClass
- 데이터를 받고있는 스레드가 돌아가는 동안, 스캐너를 통해 콘솔로 서버 및 다른 클라이언트에 전송할 데이터를 입력 한다.
- 보내는 것은 서버 클래스와 마찬가지로, 서버로 보낼 String 데이터에 담고 PrintWriter 객체를 이용해 소켓의 OutputStream에 넣는다.
- flush를 통해 보낸다.
- while 루프가 돌아가고 스레드와는 별개로 서버로 메세지 보내는 행위가 반복 됨.
* 마지막 catch문이 실행되는 경우는 소켓과 서버의 연결이 끊어진 경우이다.
예외처리문을 출력하기 보다는 콘솔 / 메세지 창이 뜨도록 설정하는 것이 UI 관점에서는 더 낫다.
// 전송할 데이터 만들기
Scanner sc = new Scanner(System.in);
// 문자열 받아오는 스레드 만들기
new ReadThread(socket).start();
while(true) {
System.out.print(">> ");
String str = sc.next();
// thread 돌리기 위해서는 언제 받을지 모르는 Receive부터 쓴 뒤 send한다
// 1. send
PrintWriter writer = new PrintWriter(socket.getOutputStream());
// getOutputStream --> 내보낼 데이터
writer.println(str); // 실질적으로 전송이 되는 문자열
writer.flush(); // 끝맺음
}
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("서버연결 시간만료!");
System.out.println("서버 연결 실패");
}
}
}
'Language > Java_basic' 카테고리의 다른 글
Thread 사용한 소켓 프로그래밍 예제 - server (0) | 2019.12.11 |
---|---|
Java Basic : day 17 - Thread의 개념과 예제 (0) | 2019.12.11 |
Java Basic : day 16 - 서버 / 클라이언트 연결하기 (0) | 2019.12.09 |
Java Basic : day 16 - 네트워크 TCP / UDP (0) | 2019.12.09 |
Java Basic : day 15 - AWT & SWING : Example - 선수 데이터 관리 프로그램 만들기 (0) | 2019.12.08 |