ⓐ TCP 방식 (연결성 통신 방법..)
실시간 통신 방식. 신뢰성이 높다.
네트워크 부담이 다소 크다.
ServerSocket, Socket
ⓑ UDP 방식 (비연결성 통신 방법..)
신뢰성의 측면에서 다소 떨어짐.
네트워크 부담이 적은편.
DatagramSocket, DatagramPacket
IP, Domain
Port : 각각의 응용 프로그램이 차지하고 있는 창구(?)
URL(Uniform Resource Locator) : 프로토콜, 도메인, 포트 등 접근하려는 URL에 대한 정보를 얻을 때 사용한다.
InetAddress : IP에 관련된 정보를 얻어올 때 사용한다.
네트워크가 연결된 후에는 소켓이 전송을 담당하게 된다.
서버의 소켓 메소드
ServerSocket serverSocket = new ServerSocket(포트번호); //서버소켓 선언
Scoket socket = serverSocket.accept(); //서버 소켓 대기
socket.getInputStream() // 읽기
socket.getOutputStream() // 쓰기
서버는 하나의 클라이언트와만 접촉하는 것이 아니므로 보통 무한 루프에서 받는다. 혹은 스레드를 사용해..
소켓은 하나의 클라이언트마다 한개의 소켓을 생성해 접근한다.
클라이언트의 소켓 메소드
Socket socket = new Socket(IP주소, 포트번호); //소켓 열기
socket.getInputStream(); //읽기
socket.getOutputStream(); //쓰기
socket.close(); //닫기
간단한 서버 예제
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerExam
{
public static void main(String[] args)
{
try
{
ServerSocket serverSocket = new ServerSocket(8000); // 서버소켓 선언
while (true)
{
System.out.println("클라이언트 접속 대기 중...");
Socket socket = serverSocket.accept(); // 서버소켓으로부터 소켓 객체 가져오기
System.out.println(socket.getInetAddress() + "가 접속되었습니다.");
// InputStream inputStream = socket.getInputStream();
// InputStreamReader inputStreamReader = new
// InputStreamReader(inputStream);
// BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
// 위의 세줄을 한줄로 표현
BufferedReader bufferedReader =
new BufferedReader(new InputStreamReader(socket.getInputStream()));
// 클라이언트로부터 메시지 입력받음
String clientMessage = bufferedReader.readLine();
// 입력받은 내용을 서버 콘솔에 출력
System.out.println("클라이언트가 보내온 내용 : " + clientMessage);
// 클라이언트에게 보내기 위한 준비
BufferedWriter bufferedWriter =
new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
bufferedWriter.write("JAVA의 세계에 오신 것을 환영합니다!");
bufferedWriter.newLine(); //readLine()으로 읽으므로 한줄끝을 알림
bufferedWriter.flush();
//PrintWriter printWriter = new PrintWriter(socket.getOutputStream(), true);
//printWriter.println("JAVA의 세계에 오신 것을 환영합니다!!");
socket.close();//접속 종료
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
간단한 클라이언트 예제
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
public class ClientExam
{
public static void main(String[] args)
{
try
{
Socket socket = new Socket("127.0.0.1", 8800);
// 서버에게 보내기 위한 준비
BufferedWriter bufferedWriter =
new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
bufferedWriter.write("안녕하세요!");
bufferedWriter.newLine(); //readLine()으로 읽기 때문에 개행 추가
bufferedWriter.flush();
BufferedReader bufferedReader =
new BufferedReader(new InputStreamReader(socket.getInputStream()));
// 서버부터 메시지 입력받음
String clientMessage = bufferedReader.readLine();
// 입력받은 내용을 서버 콘솔에 출력
System.out.println("서버가 보내온 내용 : " + clientMessage);
socket.close();//접속 종료
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
채팅 서버 예제
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import javax.swing.JFrame;
public class ChatExam
{
// 프레임 선언
private JFrame jFrame = new JFrame("채팅");
//서버 소켓 및 소켓 선언
private ServerSocket serverSocket;
private Socket socket;
//소켓들을 담을 ArrayList 선언
private ArrayList<Socket> socketList = new ArrayList<Socket>();
public ChatExam()
{
// 프레임 크기 및 보이기 설정
jFrame.setSize(500, 400);
jFrame.setVisible(true);
// swing에만 있는 X버튼 클릭시 종료
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
try
{
serverSocket = new ServerSocket(8000); // 서버소켓 선언
while( true )
{
//소켓이 생성될 때까지 대기
socket = serverSocket.accept();
// 소켓이 생성되면,
if( socketList.add(socket) )
{
new Thread()
{
@Override
public void run()
{
BufferedReader bufferedReader = null;
try
{
// 이 내용을 while문 안에 넣었을 때 문제가 생겼다.
// 다름아닌 계속해서 소켓을 새로 생성하는 문제였는데,
// 다행히 클라이언트는 소켓이 변화되지 않는다. 따라서
// 문제가 없었지만, 서버에서는 소켓이 새로 생성될 때마다 달라졌으므로 문제가
// 커졌다.
bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while( true )
{
// 클라이언트로부터 메시지 입력받음
String clientMessage = bufferedReader.readLine();
// 입력받은 메시지가 길이가 0 이상이면,
if( clientMessage.trim().length() > 0 )
{
//클라이언트 하나로부터 전달받은 메시지를 전파
ChatExam.this.spreadMessage(clientMessage);
}
if( clientMessage.contains("님이 퇴장하셨습니다. "))
{
System.out.println("퇴장했을 경우 버퍼리더 정리");
break;
}
}
}
catch (Exception e)
{
System.out.println(e + "=>server run");
}
finally
{
// 읽어오기 종료
try
{
bufferedReader.close();
}
catch (IOException e)
{
System.out.println(e + "=> ");
}
}
}
}.start(); // 스레드 실행
}
}
}
catch (Exception e)
{
System.out.println(e);
}
}
//메시지를 전파하는 메소드
public void spreadMessage(String message)
{
for( int i = socketList.size() - 1 ; i > -1 ; i-- )
{
// 클라이언트에게 보내기 위한 준비
try
{
if( !socketList.get(i).isClosed() )
{
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socketList.get(i).getOutputStream()));
bufferedWriter.write(message);
bufferedWriter.newLine();
bufferedWriter.flush();
}
else
{
socketList.remove(i);
}
}
catch (Exception e)
{
System.out.println("소켓 에러");
}
}
}
public static void main(String[] args)
{
new ChatExam();
}
}
채팅 클라이언트 예제
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class ChatClient
{
// 프레임 선언
JFrame jFrame = new JFrame("채팅");
// Swing에서의 텍스트 영역.. 스크롤바가 존재하지 않는다.
JTextArea textArea = new JTextArea("", 0, 0);// 스크롤바 없음
// Swing에서 스크롤바를 넣기 위해 아래와 같이 사용한다.
JScrollPane jScrollPane = new JScrollPane(textArea);// 스클롤바 만들기
// 내용을 입력할 입력창
JTextField inputText = new JTextField();
//소켓
Socket socket;
//이름
String name;
public ChatClient()
{
textArea.setEnabled(false);
textArea.setFocusable(false);
// 텍스트 영역 추가
jFrame.add(jScrollPane, "Center");
jFrame.add(inputText, "South");
// 프레임 크기 및 보이기 설정
jFrame.setSize(500, 400);
jFrame.setVisible(true);
// swing에만 있는 X버튼 클릭시 종료
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jFrame.addWindowListener(new WindowAdapter()
{
@Override
public void windowClosing(WindowEvent e)
{
super.windowClosing(e);
sendMessage(name + "님이 퇴장하셨습니다. ");
}
});
try
{
socket = new Socket("127.0.0.1", 8000);
}
catch (Exception e)
{
System.out.println("클라이언트 소켓 생성 에러");
}
//이름설정
do
{
name = JOptionPane.showInputDialog(this, "이름은?");
}while(name == null || name.length() < 2);
sendMessage(name + "님이 입장하셨습니다.");
jFrame.setTitle(name + "님의 채팅창");
new Thread()
{
@Override
public void run()
{
BufferedReader bufferedReader = null;
try
{
bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while ( true )
{
// 클라이언트로부터 메시지 입력받음
String clientMessage = bufferedReader.readLine();
if( clientMessage != null && clientMessage.trim().length() > 0 )
{
textArea.append(clientMessage + "\n");
textArea.setCaretPosition(textArea.getText().length());
}
}
}
catch (Exception e)
{
System.out.println(e+"=>clinet run");
e.printStackTrace();
}
finally
{
//읽어오기 종료
try
{
bufferedReader.close();
textArea.append("\n**읽어오기 종료**\n");
}
catch (IOException e)
{
System.out.println(e);
}
}
}
}.start(); // 스레드 실행
inputText.addKeyListener(new KeyAdapter()
{
@Override
public void keyReleased(KeyEvent e)
{
if( e.getKeyCode() == 10 )
{
if( inputText.getText().trim().length() > 0 )
{
sendMessage(name + " : " + inputText.getText().trim());
inputText.setText(null);
}
}
}
});
}
public void sendMessage(String message)
{
try
{
// 클라이언트에게 보내기 위한 준비
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
bufferedWriter.write(message);
bufferedWriter.newLine();
bufferedWriter.flush();
}
catch (Exception sendError)
{
System.out.println("메시지 전송 에러 : " + sendError);
}
}
public static void main(String[] args)
{
new ChatClient();
}
}