본문 바로가기
자바

자바 TCP/IP SOCKET [북붙따라하기](CLIENT,SERVER)

by 세상 모든 것 들은 그 자신을 위해 존재한다. 2020. 12. 31.

TCP/IP SOCKET 를 이용한 서버 클라이언트 통신 예제 입니다. 

먼저 SERVER 예제 입니다.

이클립스를 따로 하나더 열어서 SERVER 를 먼저 실행하고

CLIENT를 실행 해야 됩니다. 그렇지 않으면 둘중 하나는 명령창에서 실행을 해야 합니다.

 

SERVER 사용 예제 ) 코드를 복붙 하여 실행해 보시기 바랍니다.

설명은  주석과 코드 아랫부분에  있습니다.

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerSample {

	public static void main(String[] args) {
		/////////////////tcpip 소켓을 이용한 접속 서버클래스  예제 입니다.
		// 맨아래 if문에서 socket이 닫히지 않았으면 socket을 닫아야 할때를 위해서
		// try문 바깥에 선언을 먼저 해준다.try문 안쪽에 선언하면 지역 변수가 되어서 안된다.
        //서버 소켓과 TCP/IP 연결을 위한 준비를 합니다.
		ServerSocket serverSocket = null;
		InetSocketAddress isa = null;

		//모든 ip의 접속을 다 받겠다는 의미
		//특정한 ip만 받을 경우는 그아이피를 넣어주면 됩니다.
		String strServerListenIp = "0.0.0.0";

		//외부포트는 임의로 정해 준것입니다. 
		//앞쪽에 낮은번호는 예약이 되어 있어 
		//임의 사용이 가능한 뒸쪽의 번호를 사용함
		int nServerListenPort = 8888;

		try {
			// 소켓을 생성합니다.
			serverSocket = new ServerSocket();

			// 접속받을 범위 와 포트를 지정합니다.
			isa = new InetSocketAddress(strServerListenIp, nServerListenPort);

			// 바인딩을 하고 CLIENT가 접속해오기를 기다립니다.(listen....)
			serverSocket.bind(isa);

			while (true) {
				System.out.println("Listening ....");

				// 연결이 되면 연결된 클라이 언트에 대한 소켓을 생성함
				// 연결이 오면 바로 받음
				Socket socket = serverSocket.accept();

				// tcp/ip로 연결된 소켓의 정보를 얻기 위해 InetSocketAddress를 사용
				isa = (InetSocketAddress) socket.getRemoteSocketAddress();

				System.out.printf("요청한 연결을 확인함 :  [%s] [%d]\n " , isa.getHostName(),nServerListenPort);
			}
		} catch (Exception e) {
		}

		if (!serverSocket.isClosed()) {
			try {
				serverSocket.close();
			} catch (IOException e1) {
			}
		}

	}

}

//결과는 :

//Listening ....
//요청한 연결을 확인함 :  [127.0.0.1] [8888]
//Listening ....

 

 

네트워크 통신 포트 간략한 설명 입니다.

0번 ~ 1023번 : 까지는 예약된(잘알려진) 포트 입니다. 

   .FTP,HTTP,TELNET 등 이 있습니다.

1024번 ~ 49151번: 등록된 포트 (registered port)

49152번 ~ 65535번: 동적 포트 (dynamic port)

 

0번 부터 1023까지만 임의로 사용하지 않으면 문제는 없는것 같습니다.

 

 

CLIENT 사용 예제 ) 코드를 복붙 하여 실행해 보시기 바랍니다.

설명은  주석과 코드 아랫부분에  있습니다.

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;

public class ClientSample {

	public static void main(String[] args) {
		// 맨아래 if문에서 socket이 닫히지 않았으면 socket을 닫아야 할때를 위해서
		// try문 바깥에 선언을 먼저 해준다.try문 안쪽에 선언하면 지역 변수가 되어서 안된다.
		
		//자기PC의 루프백 아이피 입니다. localhost와 같습니다.
		String strServerIP = "127.0.0.1"; 
		
		//외부포트는 임의로 정해 준것입니다. 
		//앞쪽에 낮은번호는 예약이 되어 있어 
		//임의 사용이 가능한 뒸쪽의 번호를 사용함
		int nServerPort = 8888;
		
		//네트워크 접속시 기다리는 시간을 정함.
		int nDelayTime=10000;
		
		InetSocketAddress isaSvr = null;
		Socket socket = null;

		try {
			socket = new Socket();

			System.out.println("서버와 연결을 시도 합니다....");

			isaSvr = new InetSocketAddress(strServerIP, nServerPort);
			
			socket.connect(isaSvr, nDelayTime);
			
			System.out.printf("연결이 성공 되었습니다.[%s] [%d]\n",strServerIP, nServerPort);

		} catch (Exception e) {
		}

		if (!socket.isClosed()) {
			try {
				socket.close();
			} catch (IOException e1) {
				System.out.println("예외 발생 : " + e1.getLocalizedMessage());
			}
		}

	}
}
//결과는 :

//서버와 연결을 시도 합니다....
//연결이 성공 되었습니다.[127.0.0.1] [8888]

 

지금 서버와 클라이언트의 연결 예제는

서버는 WHILE 문으로 무한 반복하면서 기다리는 경우이고

클라이 언트는 접속 하자 마자 바로 연결을 끊는 경우 입니다.

 

실제 코딩을 할때는 이렇게 하면 데이터를 전달 할수 없습니다.

접속후 데이터를 주고 또는 주고 받은 후에 접속을 끊을것인지 유지 할것인지를 결정합니다.

실전에서는 클라이언트가 여러대 인경우 가 많으므로 서버에서 쓰레드를 사용해서 사용을 합니다.

 

아래는 실전 서버예제 입니다.

소켓용 통신 프로 그램이 필요 하시면 제가 만든 (허접하지만) 것을 보내드리겠습니다.

댓글 달아주세요. 양이 많아 여기에 올리기는 어렵네요..

public class TcpServerDiary {

	private int nClientCnt;	// 현재 클라이언트 수
	private final int nMaxClient=10;
	
	
	public static void main(String[] args) {

		TcpServerDiary im = new TcpServerDiary();
		im.nClientCnt=0;
		
		ServerSocket sockSvr = null; // 서버 소켓
		Socket sockChild = null; // 차일드 소켓
		InetSocketAddress isaSvr = null; // 서버 엔드포인트
		InetSocketAddress isaCld = null; // 클라이언트 엔드포인트

		String strListenIP = "0.0.0.0"; // 리슨 IP
		int nListenPort = 8888; // 리슨 포트

		try {
			
			// 서버 소켓 생성
			sockSvr = new ServerSocket();
			isaSvr = new InetSocketAddress(strListenIP, nListenPort);
			sockSvr.bind(isaSvr);

			// 무한루프의 시작
			while(true) {
			
				System.out.printf("Server--[MSG] 서버 시작 [%s:%d]\n", strListenIP, nListenPort);
				System.out.printf("Server--[MSG] 접속자 수 = [%d]\n", im.getClientCnt());
				
				sockChild = sockSvr.accept(); // Listen & Accept
				sockChild.setSoLinger(true, 0);

				// 접속한 클라이언트 정보 처리
				isaCld = (InetSocketAddress) sockChild.getRemoteSocketAddress();
				System.out.printf("Server--[MSG] 접속자는  [%s:%d] 연결됨 !! \n", isaCld.getHostName(), isaCld.getPort());
	
				// 동시 클라이언트 확인
				if(im.getClientCnt()==im.nMaxClient)
				{
					//System.out.printf("[MSG] Client Count=[%d]\n", im.getClientCnt());
					sockChild.close();
					System.out.printf("Server--[MSG] 새로운 접속자 (%s:%d) \n"
							,isaCld.getHostName(), isaCld.getPort());
					System.out.println();
					continue;
				}
				
				// 차일드 소켓에 대한 이관 처리
				//sockChild.close();
				String strChildName=String.format("CHILD-%s-%d"
						,isaCld.getHostName(), isaCld.getPort());
				TCPSvrChild3 svrChild=new TCPSvrChild3(
						strChildName, sockChild, isaCld, im);
				svrChild.start();
				im.incClientCnt();
				System.out.printf("Server--[MSG] 접속자 수 =[%d]\n", im.getClientCnt());
				
				System.out.println();
				
			} // end of while
			// 무한루프의 범위	
		
		} catch (Exception e) {

			//System.out.println("Server--[EXP] " + e.getLocalizedMessage());

		} finally {
			try {				
				if (sockSvr != null) {
					if(!sockSvr.isClosed())
						sockSvr.close();
					System.out.printf("Server--서버 소켓(%d) 닫힘!\n", nListenPort);
				}
			} catch (Exception e) {}
		}

	}

설명끝.

 

 

 

 

728x90
반응형

댓글