3-3. 소켓 프로그래밍을 이해하기 위한 예제(3)
: 예제(2)에서 했던 코드를 Socekt 클래스에 정의된 getPort()와 getLocalPort()로 수정한 예제이다.
package Networking;
import java.net.*;
import java.io.*;
import java.util.Date;
import java.text.SimpleDateFormat;
public class Exercise008 {
public static void main(String args[]) {
ServerSocket serverSocket = null;
try {
// 서버소켓을 생성하여 7777번 포트와 결합(bind)시킨다.
serverSocket = new ServerSocket(7777);
System.out.println(getTime()+"서버가 준비되었습니다.");
} catch(IOException e) {
e.printStackTrace();
}
while(true) {
try {
// 서버소켓
System.out.println(getTime()+"연결요청을 기다립니다.");
Socket socket = serverSocket.accept();
System.out.println(getTime()+ socket.getInetAddress() + "로부터 연결요청이 들어왔습니다.");
System.out.println("getPort():"+socket.getPort());
System.out.println("getLocalPort():" +socket.getLocalPort());
// 소켓의 출력스트림을 얻는다.
OutputStream out = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(out);
// 원격 소켓(remote socket)에 데이터를 보낸다.
dos.writeUTF("[Notice] Test Message1 from Server.");
System.out.println(getTime()+"데이터를 전송했습니다.");
// 스트림과 소켓을 닫아준다.
dos.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
} // while
} // main
// 현재시간을 문자열로 반환하는 함수
static String getTime() {
SimpleDateFormat f = new SimpleDateFormat("[hh:mm:ss]");
return f.format(new Date());
}
} // class
( getPort()가 반환하는 값은 상대편 소켓의 포트이다. )
( getLocalPort()는 소켓 자신이 사용하는 포트이다. )
( 이를 통해 알 수 있는 것은 서버 소켓이 7777번 포트를 사용하고 있어도, 서버 소켓이 아닌 소켓은
7777번 포트를 사용할 수 있다는 것이다. )
( 클라이언트 프로그램의 소켓이 사용하는 포트는 사용가능한 임의의 포트가 선택된다. )
3-4. 소켓 프로그래밍을 이해하기 위한 예제(4)
: 클라이언트 프로그램으로부터 5초동안 아무런 요청이 없다면 서버를 닫는 예제이다.
package Networking;
import java.net.*;
import java.io.*;
import java.util.Date;
import java.text.SimpleDateFormat;
public class Exercise009 {
public static void main(String args[]) {
ServerSocket serverSocket = null;
try {
// 서버소켓을 생성하여 7777번 포트와 결합(bind)시킨다.
serverSocket = new ServerSocket(7777);
System.out.println(getTime()+"서버가 준비되었습니다.");
} catch(IOException e) {
e.printStackTrace();
}
while(true) {
try {
// 서버소켓
System.out.println(getTime()+"연결요청을 기다립니다.");
// 요청대기시간을 5초로 설정한다.
// 5초동안 접속요청이 없으면 SocketTimeoutException이 발생한다.
serverSocket.setSoTimeout(5*1000);
Socket socket = serverSocket.accept();
System.out.println(getTime()+ socket.getInetAddress() + "로부터 연결요청이 들어왔습니다.");
// 소켓의 출력스트림을 얻는다.
OutputStream out = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(out);
// 원격 소켓(remote socket)에 데이터를 보낸다.
dos.writeUTF("[Notice] Test Message1 from Server.");
System.out.println(getTime()+"데이터를 전송했습니다.");
// 스트림과 소켓을 닫아준다.
dos.close();
socket.close();
} catch (SocketTimeoutException e) {
System.out.println("지정된 시간동안 접속요청이 없어서 서버를 종료합니다.");
System.exit(0);
} catch (IOException e) {
e.printStackTrace();
}
} // while
} // main
// 현재시간을 문자열로 반환하는 함수
static String getTime() {
SimpleDateFormat f = new SimpleDateFormat("[hh:mm:ss]");
return f.format(new Date());
}
} // class
( setTimeout(int timeout)을 사용하여 대기시간을 지정할 수 있다. )
( 만약 지정한 대기시간이 지난다면, accept()에서 SocketTimeoutException이 발생하므로 Catch문을
적절히 처리할 수 있다. )
3-5. 소켓 프로그래밍을 이해하기 위한 예제(5)
: 여러 개의 쓰레드를 생성해서 클라이언트의 요청을 동시에 처리하도록 하는 예제이다.
package Networking;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Exercise010 implements Runnable{
ServerSocket serverSocket;
Thread[] threadArr;
public static void main(String args[]) {
// 5개의 쓰레드를 생성하는 서버를 생성한다.
Exercise010 server = new Exercise010(5);
server.start();
} // main
public Exercise010(int num) {
try {
// 서버소켓을 생성하여 7777번 포트와 결합(bind)시킨다.
serverSocket = new ServerSocket(7777);
System.out.println(getTime()+"서버가 준비되었습니다.");
threadArr = new Thread[num];
} catch(IOException e) {
e.printStackTrace();
}
}
public void start() {
for(int i=0; i < threadArr.length; i++) {
threadArr[i] = new Thread(this);
threadArr[i].start();
}
}
public void run() {
while(true) {
try {
System.out.println(getTime()+ "가 연결요청을 기다립니다.");
Socket socket = serverSocket.accept();
System.out.println(getTime()+ socket.getInetAddress() + "로부터 연결요청이 들어왔습니다.");
// 소켓의 출력스트림을 얻는다.
OutputStream out = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(out);
// 원격 소켓(remote socket)에 데이터를 보낸다.
dos.writeUTF("[Notice] Test Message1 from Server.");
System.out.println(getTime()+"데이터를 전송했습니다.");
// 스트림과 소켓을 닫아준다.
dos.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
} // while
} // run
// 현재시간을 문자열로 반환하는 함수
static String getTime() {
String name = Thread.currentThread().getName();
SimpleDateFormat f = new SimpleDateFormat("[hh:mm:ss]");
return f.format(new Date()) + name ;
}
} // class
( 이처럼 클라이언트의 수가 많을 때는 쓰레드를 이용해서 클라이언트의 요청을 병렬적으로 처리하는 것이 좋다. )
다음장
소켓 프로그래밍: TCP와 UDP(3) (tistory.com)
소켓 프로그래밍: TCP와 UDP(3)
kind-coding.tistory.com
'자바 > 네트워킹' 카테고리의 다른 글
소켓 프로그래밍: TCP와 UDP(4) (0) | 2022.05.02 |
---|---|
소켓 프로그래밍: TCP와 UDP(3) (0) | 2022.05.02 |
소켓 프로그래밍: TCP와 UDP(1) (0) | 2022.05.01 |
네트워킹(Networking) (2) - URL, URLConnection (0) | 2022.04.30 |
네트워킹(Networking) (1) - InetAddress (0) | 2022.04.30 |