Server
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.EOFException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class Server extends JFrame {
private JTextField enterField; // 사용자로부터 메시지를 받음
private JTextArea displayArea; // 사용자에게 정보를 보여줌
private ObjectOutputStream output; // 클라이언트에 보낼 출력 스트림
private ObjectInputStream input; // 클라이언트로부터 받을 입력 스트림
private ServerSocket server; // 서버 소켓
private Socket connection; // 클라이언트와 연결하는 소켓
private int counter = 1; // 연결 횟수의 카운터
//GUI를 설정함
public Server(){
super("Server");
enterField = new JTextField(); // enterField를 생성함
enterField.setEditable(false);
enterField.addActionListener(
new ActionListener() {
//클라이언트에 메시지를 보냄
@Override
public void actionPerformed( ActionEvent event ) {
// TODO Auto-generated method stub
sendData(event.getActionCommand());
enterField.setText("");
} //actionperformed 메소드 끝
} // 익명 내부 클래스 끝
); // addActionListener 호출 끝
add( enterField, BorderLayout.NORTH);
displayArea = new JTextArea(); // displayArea를 생성함
add( new JScrollPane(displayArea), BorderLayout.CENTER);
setSize(300, 150); //윈도의 크기를 설정함
setVisible(true); // 윈도를 표시함
} // Server 생성자 끝
public void runServer(){
try{ // 서버가 연결 요청을 받도록 설정하고, 연결을 처리함
server = new ServerSocket(12345, 100); // ServerSocket을 생성함
while(true){
try{
waitForConnection(); // 연결 요청을 기다림
getStreams(); // 입/출력 스트림을 얻어옴
processConnection(); // 연결 처리를 수행함
} // try 블록 끝
catch(EOFException eofException){
displayMessage("\nServer terminated connection");
} // catch 블록 끝
finally{
closeConnection(); // 연결을 끊음
counter++;
} // finally 블록 끝
} // while 문 끝
} // try 블록 끝
catch(IOException ioException){
ioException.printStackTrace();
} // catch 블록 끝
} // runServer 메소드 끝
// 연결 요청이 도착할 때까지 기다리고, 도착하면 연결 정보를 표시함
private void waitForConnection() throws IOException{
displayMessage("Waiting for connection\n");
connection = server.accept(); // 서버가 연결 요청을 승인하게 함
displayMessage("Connection "+counter+" received from: "+connection.getInetAddress().getHostName());
} // waitForConnection 메소드 끝
// 데이터를 주고받을 스트림을 얻어옴
private void getStreams() throws IOException{
//객체에 대한 출력 스트림을 설정함
output = new ObjectOutputStream(connection.getOutputStream());
output.flush(); // 헤더 정보를 보내기 위해 출력 버퍼를 비움
// 객체에 대한 입력 스트림을 설정함
input = new ObjectInputStream(connection.getInputStream());
displayMessage("\nGot I/O streams\n");
} // getStreams 메소드 끝
// 클라이언트와 연결을 처리함
private void processConnection() throws IOException{
String message = "Connection successful";
sendData( message ); // 연결 요청이 성공했다는 메시지를 클라이언트에 보냄
// enterField를 활성화해서 서버 사용자가 메시지를 보낼 수 있도록 함
setTextFieldEditable(true);
do{ // 클라이언트가 서버에 보낸 메시지를 처리함
try{
message = (String) input.readObject(); // 새로운 메시지를 읽음
displayMessage("\n" + message); // 메시지를 표시함
} // try 블록 끝
catch(ClassNotFoundException classNotFoundException){
displayMessage("\nUnknown object type received");
} // catch 블록 끝
}while(!message.equals("CLIENT>>> TERMINATE"));
} // processConnection 메소드 끝
// 스트림과 소켓의 연결을 끊음
private void closeConnection(){
displayMessage("\nTerminating connection\n");
setTextFieldEditable(false); // enterfield를 비활성화함
try{
output.close(); // 출력 스트림을 닫음
input.close(); //입력 스트림을 닫음
connection.close(); // 소켓을 닫음
} // try 블록 끝
catch(IOException ioException){
ioException.printStackTrace();
} // catch 블록 끝
} // closeConnection 메소드 끝
// 클라이언트에 메시지를 보냄
private void sendData(String message){
try{ // 클라이언트에 객체를 보냄
output.writeObject("SERVER>>> " + message);
output.flush(); // 클라이언트에 보낼 출력 버퍼를 비움
displayMessage("\nSERVER>>> " + message);
} // try 블록 끝
catch(IOException ioException){
displayArea.append("\nError writing object");
} // catch 블록 끝
} // sendData 메소드 끝
// 이벤트 전달 스레드에 있는 displayArea를 조작함
private void displayMessage( final String messageToDisplay){
SwingUtilities.invokeLater(
new Runnable() {
@Override
public void run() { // displayArea를 갱신함
// TODO Auto-generated method stub
displayArea.append(messageToDisplay); // message를 추가함
} // run 메소드 끝
} // 익명 내부 클래스 끝
); // SwingUtilities.invokeLater 호출 끝
} // displayMessage 메소드 끝
// 이벤트 전달 스레드에 있는 enterField를 조작함
private void setTextFieldEditable(final boolean editable){
SwingUtilities.invokeLater(
new Runnable() {
@Override
public void run() { // enterField의 편집 활성화를 설정함
// TODO Auto-generated method stub
enterField.setEditable(editable);
} // run 메소드 끝
} // 내부 클래스 끝
); // SwingUtilities.invokeLater 호출 끝
} // setTextFieldEditable 메소드 끝
} // Server 클래스 끝