2008년 10월 28일
네트워크 프로그래밍.
이번글은 네트워크 프로그래밍에 대해서 이야기 하고자 합니다.
먼저 네트워크 프로그래밍에 대해서 이야기 하기 전에 자바 입출력에 관한 이야기를 잠시 하고자 합니다.
자바 프로그래밍에서 입출력이라고 한다면 보통
화면에 보여주는 출력, 키보드 입력을 받아들이는 입력, 파일을 읽고 쓰는 파일 입출력을 떠올릴 수가 있죠.
이 이야기를 하는 이유는 네트워크 프로그래밍 역시 입출력에 해당 한다고 말하고 싶어서 입니다.
통신 또한 들어오는 것과 나가는 것이 있는 입출력 시스템이니까요.
그럼 네트워크 프로그래밍에 대해서 알아보도록 합시다.
보통 네트워크 통신은 IP 주소를 이용해서 한다고 알고 있는게 상식입니다. 그리고 한가지 요소를 더 말하자면 포트라는 것도 있어야 하죠. 이 정도는 네트워크에 대한 상식이니까 반드시 까먹지 말고 ~ 기억합시다.
그럼 이제 시작합시다.
먼저 Socket 클래스에 대해서 알아봅시다. 이 클래스는 java.net 패키지에 존재 하는 녀석입니다.
Socket 클래스를 간단하게 말하면 위에서 말한 IP와 포트를 담당한다고 생각하면 쉽습니다.
API에서 Socket 클래스에 대한 것을 보면 생성자에 Socket(주소, 포트) 메소드가 존재합니다.
실제로 소켓 프로그래밍을 하고 실행을 하면 해당 포트를 컴퓨터에서 개방 하는 것을 알수 있습니다.
아마 WindowsXP 환경에서 작업을 해보시면 방화벽이 동작하는 경우가 있습니다.
실행 할 때 포트 개방 문제 때문이지요.. 과연 차단 할 것인가 실뢰 할 것인가에 대한 질의를 받게 됩니다.
그럼 다음으로 넘어가서 입출력에 관한 이야기를 다시 꺼내고자 합니다.
서버와 클라이언트가 통신을 한다고 가정을 해봅시다.
클라이언트가 서버에게 데이터 또는 메시지를 전달합니다.
- 클라이언트 입장에서는 출력에 해당합니다.
- 서버 입장에서는 입력에 해당합니다.
서버는 클라이언트로 부터 데이터 또는 메시지를 전달받습니다.
- 서버는 입력에 해당합니다.
- 만약 서버가 클라이언트에게 다시 전달 한다면 출력에 해당 합니다.
위에 특징을 보면 입출력에 대한 것과 다를 것이 없어 보이죠? 그래서 입출력에 관한 이야기를 한 것입니다.
일단은 클라이언트 입장에서 입출력을 보도록 합시다.
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
bis = new BufferedInputStream(socket.getInputStream());
bos = new BufferedOutputStream(socket.getOutputStream());
소스를 보면 바이트스트림을 이용한 것을 알 수 있습니다. 데이터 또는 메시지라고 했는데 주위 합시다. 통신은 모두 데이터를 전송 하거나 전송 받는 것이라는 것을 말입니다. 뭐 OSI 참조모델을 알고 있다면 생각해보시길 바랍니다.
클라이언트 입장에서는 bos를 통해서 서버에게 전달을 하게 됩니다.
그럼 당연히 서버에게 전달 받을 떄는 bis로 받게 됩니다.
여기서 어떻게? 왜? 라는 의문을 갖을 수 있는데 socket.getOutputStream() 이 라인을 주의깊게 보시면 알수 있다고 생각됩니다.
그럼 실제로 전송은 어떻게 할까요?
우리가 입출력에서 배운 것이 있습니다. 파일을 쓸 때는 write()를 이용했었습니다.
이것과 동일하게 해주면 됩니다.
예)
bos.write(전송할 것은 여기 안에 ~);
그럼 반대로 전송을 받을 때는???
예)
String str = null;
byte echo[] = new byte[256];
int len = 0;
while((len = bis.read(echo,0,echo.length))!=-1){
str = new String(echo,0,len);
}
System.out.println(str);
우리가 알고 있는 read() 메소드 활용법과 동일하죠? 이런식으로 하면 됩니다.
잠깐 중간정리를 해보자면
네트워크 프로그래밍에서 데이터를 주고 받을 때는 소켓을 이용하고, 원리를 간단히 정리하면 소켓+입출력이다. 라고 할 수 있습니다.
그리고 이 부분에서 틀리기 쉬운 점이 있다면 try{}catch(Exception e){}를 써야 한다는 점과 입출력을 이용하므로 close(), flush()와 같은 흐름을 닫아 주는 메소드의 활용일 것이라 예상 됩니다.
그럼 이와 매우 유사하지만 서버 쪽은 약간 다른 부분이 있어서 그 부분만 집고 넘어가도록 하겠습니다.
보통 웹상에서 제공 받는 모든 서비스는 우리가 서버에게 요청을 하기 때문에 서비스를 이용받을 수 있습니다. 그렇게 때문에 서버는 항상 클라이언트를 항상 기다리고 있어야 합니다. 그렇기 때문에 입력을 대기하고 있어야 하겠죠..
이러한 역할을 해주는 클래스가 ServerSocket 클래스 입니다. 이 클래스를 이용해서 클라이언트의 요청이 있을 때 까지 대기했다가 요청이 있으면 역할을 하게 됩니다.
ServerSocket server = null;
server = new ServerSocket(port);
Socket con = server.accept();
위와 같이 활용합니다. 실제로 server = new ServerSocket(port); 이 라인은 Socket 클래스와 비슷합니다.
server.accept(); 이 라인이 대기 했다가 요청이 있으면 다음에 정해진 역할을 하게 됩니다.
서버 역시
BufferedInputStream bis = new BufferedInputStream(con.getInputStream());
BufferedOutputStream bos = new BufferedOutputStream(con.getOutputStream());
이런식으로 클라이언트에게서 입력을 받아서 입출력 처리를 합니다.
그럼 이정도로 이야기 하고 예제와 실행 예를 보여드리도록 하겠습니다.
주석이 없으니 이해를 하시려면 API를 참고 하셔야 합니다.

import java.net.*;
import java.io.*;
public class DBTransfer {
private Socket socket = null;
private BufferedInputStream bis = null;
private BufferedOutputStream bos = null;
public DBTransfer(String address,int port){
try{
socket = new Socket(address,port);
bis = new BufferedInputStream(socket.getInputStream());
bos = new BufferedOutputStream(socket.getOutputStream());
}catch(Exception e){
e.printStackTrace();
}
}
public void send(byte []query){
try{
bos.write(query);
bos.flush();
}catch(Exception e){
e.printStackTrace();
}
}
public void receive(){
try{
String str = null;
byte echo[] = new byte[256];
int len = 0;
while((len = bis.read(echo,0,echo.length))!=-1){
str = new String(echo,0,len);
}
System.out.println(str);
System.out.println("메시지 전송 완료");
}catch(Exception e){
e.printStackTrace();
}
}
public void close(){
try{
bos.close();
bis.close();
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String[] args) {
String address = "linux.iptime.org";
int port = 9000;
String str;
byte []buf = null;
while(true){
try{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
str = br.readLine();
buf = str.getBytes();
}catch(Exception e){
e.printStackTrace();
}
byte []query = ("zzzz)").getBytes();
DBTransfer client = new DBTransfer(address,port);
client.send(buf);
client.receive();
client.close();
}}
}
---------------------------------------------------------------
import java.net.*;
import java.io.*;
public class DBServer {
private ServerSocket server = null;
public DBServer(int port){
try{
server = new ServerSocket(port);
}catch(Exception e){
e.printStackTrace();
}
}
public void process(){
while(true){
try{
Socket con = server.accept();
BufferedInputStream bis = new BufferedInputStream(con.getInputStream());
BufferedOutputStream bos = new BufferedOutputStream(con.getOutputStream());
String query = null;
byte []buf = new byte[256];
int len = 0;
while((len=bis.read(buf,0,buf.length))!= -1){
query = new String(buf,0,len);
bos.write(buf,0,len);
bos.flush();
if((query.indexOf(""))!= -1){
break;
}
}
System.out.println(query);
bos.close();
bis.close();
con.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
public static void main(String[] args) {
int port = 9000;
DBServer server = new DBServer(port);
server.process();
}
}
# by | 2008/10/28 22:05 | 정리할 자료들 | 트랙백 | 덧글(2)





☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]