Socket 프로그래밍 및mina 프레임워크 간단한 예

클라이언트와 서버의 긴 연결을 실현하려면 socket 방식으로 서버와 클라이언트를 연결할 수 있습니다.이 글은 소켓의 서버 측과 클라이언트를 원생 방식으로 실현하고 미나 프레임워크로 다시 한 번 실현할 것이다.원래 방식: 클라이언트는 다음과 같이 수행할 수 있습니다. SocketClient:
package socketClient;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;

public class SocketClient {

    public int port = 9898;
    public String hostAddress = "127.0.0.1";

    public static void main(String[] args) {
        SocketClient client = new SocketClient();
        client.start();
    }

    private void start() {
        BufferedReader inputReader = null;
        OutputStreamWriter output = null;
        Socket socket = null;
        try {
            socket = new Socket(hostAddress, port);
            inputReader = new BufferedReader(new InputStreamReader(System.in));
            output = new OutputStreamWriter(socket.getOutputStream());
            String inputContent;
            int count = 0;
            while (!(inputContent = inputReader.readLine()).equals("bye")) {
                output.write(inputContent);
                    output.write("
"
); output.flush(); getServerMsg(socket); } } catch (IOException e) { e.printStackTrace(); } finally { try { output.close(); inputReader.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } } private void getServerMsg(Socket socket) { new Thread(new Runnable() { @Override public void run() { BufferedReader reader = null; try { reader = new BufferedReader(new InputStreamReader( socket.getInputStream())); String serverMsg; while ((serverMsg = reader.readLine()) != null) { System.out.println("server say: " + serverMsg); } } catch (IOException e) { e.printStackTrace(); } finally { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } } }).start(); } }

서버 측:
package com.socket.tra;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class SocketServer {

    public static void main(String[] args) {
        SocketServer server = new SocketServer();
        server.startServer();
    }

    private void startServer() {
        ServerSocket serverSocket = null;
        Socket socket = null;
        try {
            serverSocket = new ServerSocket(9898);
            while (true) {
                socket = serverSocket.accept();
                System.out.println(socket.hashCode() + " is connect");
                connect(socket);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void connect(final Socket socket) {
        new Thread(new Runnable() {

            public void run() {
                BufferedReader reader = null;
                OutputStreamWriter writer = null;

                try {
                    reader = new BufferedReader(new InputStreamReader(
                            socket.getInputStream()));
                    writer = new OutputStreamWriter(socket.getOutputStream());
                    String msg;
                    while ((msg = reader.readLine()) != null) {
                        System.out.println(socket.hashCode()+"say: "+msg);
                        writer.write(msg + "
"
); writer.flush(); } } catch (IOException e) { e.printStackTrace(); } finally { try { writer.close(); reader.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } } }).start(); } }

이것은 socket의 기본적인 용법이지만 실제 개발에서 우리는 일반적으로 봉인된 프레임워크로 실현한다. 아파치미나는 사용자가 고성능과 고신축성 네트워크 응용 프로그램을 개발하는 데 도움을 줄 수 있는 프레임워크이다.이것은 Javanio 기술을 통해 TCP/IP와 UDP/IP 프로토콜을 바탕으로 추상적이고 이벤트 구동적이며 비동기적인 API를 제공한다.구체적인 용법은 홈페이지에 가서 알아보고 여기서 간단한 사용 예시를 제공하여 위의 원생 방법과 같은 기능을 실현할 수 있다.버전 1: 서버 측:
package com.socket;

import java.io.IOException;
import java.net.InetSocketAddress;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;

public class Main {
    public static int port = 9898;
    public static void main(String[] args) {

        NioSocketAcceptor acceptor = new NioSocketAcceptor();

        try {
            // handler
            acceptor.setHandler(new MyHandler());
            // 
            acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory()));
            // 
            acceptor.bind(new InetSocketAddress(port));

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

MyHandler:
package com.socket;

import org.apache.mina.core.service.IoHandler;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;

public class MyHandler implements IoHandler {

    public void exceptionCaught(IoSession arg0, Throwable arg1)
            throws Exception {
        System.out.println("exception");
    }

    public void inputClosed(IoSession arg0) throws Exception {
        System.out.println("inputClosed");
    }

    public void messageReceived(IoSession arg0, Object arg1) throws Exception {
        String msg = (String) arg1;
        System.out.println("messageReceived server: " + msg);
        arg0.write(msg);
    }

    public void messageSent(IoSession arg0, Object arg1) throws Exception {
        System.out.println("messageSent");
    }

    public void sessionClosed(IoSession arg0) throws Exception {
        System.out.println("sessionClosed "+arg0.hashCode());
    }

    public void sessionCreated(IoSession arg0) throws Exception {
        System.out.println("sessionCreated "+arg0.hashCode());

    }

    public void sessionIdle(IoSession arg0, IdleStatus arg1) throws Exception {
        System.out.println("sessionIdle "+arg0.hashCode()+" , "+arg1);
    }

    public void sessionOpened(IoSession arg0) throws Exception {
        System.out.println("sessionOpened "+arg0.hashCode());
    }

}

클라이언트:
package socketClient.mina;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.InetSocketAddress;
import java.net.Socket;

import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.transport.socket.nio.NioSocketConnector;

public class SocketClient {

    public int port = 9898;
    public String hostAddress = "127.0.0.1";

    public static void main(String[] args) throws IOException {

        NioSocketConnector connector = new NioSocketConnector();
        connector.setHandler(new MyClientHandler());
        connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory()));
        ConnectFuture future = connector.connect(new InetSocketAddress("127.0.0.1", 9898));
        future.awaitUninterruptibly();// 
        IoSession session = future.getSession();
        BufferedReader inputReader = new BufferedReader(new InputStreamReader(System.in));
        String inputContent;
        while (!(inputContent = inputReader.readLine()).equals("bye")) {
            session.write(inputContent);
        }

    }


}

MyClientHandler:
package socketClient.mina;

import org.apache.mina.core.service.IoHandler;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;

public class MyClientHandler implements IoHandler {

    public void exceptionCaught(IoSession arg0, Throwable arg1)
            throws Exception {
        System.out.println(arg1.getCause());
    }

    public void inputClosed(IoSession arg0) throws Exception {
//      System.out.println("inputClosed");
    }

    public void messageReceived(IoSession arg0, Object arg1) throws Exception {
        String msg = (String) arg1;
        System.out.println("client messageReceived: " + msg);
    }

    public void messageSent(IoSession arg0, Object arg1) throws Exception {
        System.out.println("client messageSent->" + (String)arg1);
    }

    public void sessionClosed(IoSession arg0) throws Exception {
        System.out.println("sessionClosed "+arg0.hashCode());
    }

    public void sessionCreated(IoSession arg0) throws Exception {
        System.out.println("sessionCreated "+arg0.hashCode());



    }

    public void sessionIdle(IoSession arg0, IdleStatus arg1) throws Exception {
        System.out.println("sessionIdle "+arg0.hashCode()+" , "+arg1);
    }

    public void sessionOpened(IoSession arg0) throws Exception {
        System.out.println("sessionOpened "+arg0.hashCode());
    }

}

버전 1은 프레임워크가 작성된 TextLine CodecFactory를 사용하여 문자열을 해석하는데 실제 실용적인 상황에서 사용자 정의 해석 기능을 사용해야 하기 때문에 버전 2는 문자열 해석 기능을 스스로 쓴다.버전 2: 서버 쪽: Main: 주 함수 MyDecoder: 데이터 디코딩 MyEncoder: 데이터 인코딩 MyHandler: MyProtocolFactory: 인코딩 및 디코더 생성 MyCumulative Encoder: 데이터 인코딩을 실현하여 서버 데이터를 캐시하여 데이터 분실을 방지합니다.
Main:
package com.socket.r1;

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

import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;

public class Main {
    public static int port = 9898;
    public static void main(String[] args) {
        NioSocketAcceptor acceptor = new NioSocketAcceptor();

        try {
            acceptor.setHandler(new MyHandler());
            acceptor.getFilterChain().addLast("logger", new LoggingFilter());
            acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new MyProtocolCodecFactory()));
            acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 125);
            acceptor.bind(new InetSocketAddress(port));     

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

MyDecoder:
package com.socket.r1;

import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;

public class MyDecoder implements ProtocolDecoder {

    public void decode(IoSession session, IoBuffer in, ProtocolDecoderOutput output)
            throws Exception {
        // 
        int startPosition = in.position();
        while(in.hasRemaining()){
            byte b = in.get();
            if(b == '
'
){ int curPosition = in.position(); // int limit = in.limit(); // in.position(startPosition); // in.limit(curPosition); IoBuffer buf = in.slice(); byte[] bytes = new byte[buf.limit()]; // bytes buf.get(bytes); String str = new String(bytes); output.write(str); in.position(curPosition); in.limit(limit); } } } public void dispose(IoSession arg0) throws Exception { System.out.println("dispose" + arg0.hashCode()); } public void finishDecode(IoSession arg0, ProtocolDecoderOutput arg1) throws Exception { System.out.println("finishDecode" + arg0.hashCode()); } }

MyEncoder:
package com.socket.r1;

import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;

import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolEncoder;
import org.apache.mina.filter.codec.ProtocolEncoderOutput;

public class MyEncoder implements ProtocolEncoder {

    public void dispose(IoSession arg0) throws Exception {
        System.out.println("dispose" + arg0.hashCode());    
    }

    public void encode(IoSession arg0, Object msg, ProtocolEncoderOutput output)
            throws Exception {

        String s= null;
        if(msg instanceof String){
            s = (String) msg;
        }
        if(s!=null){
            CharsetEncoder charsetEncoder = (CharsetEncoder) arg0.getAttribute("encoder");
            if(charsetEncoder ==null){
                charsetEncoder = Charset.defaultCharset().newEncoder();
                arg0.setAttribute("encoder",charsetEncoder);
            }
            IoBuffer ioBuffer = IoBuffer.allocate(s.length());
            ioBuffer.setAutoExpand(true);
            ioBuffer.putString(s, charsetEncoder);
            ioBuffer.flip();
            output.write(ioBuffer);
        }


    }

}

MyHandler는 버전 1과 마찬가지로 코드를 붙이지 않습니다.MyCumulativeDecoder :
package com.socket.r1;

import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;

public class MyCumulativeDecoder extends CumulativeProtocolDecoder {

    /**
     *  return true
     */
    @Override
    protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput output)
            throws Exception {
        int startPosition = in.position();
        while(in.hasRemaining()){
            byte b = in.get();
            if(b == '
'
){ int curPosition = in.position(); int limit = in.limit(); in.position(startPosition); in.limit(curPosition); IoBuffer buf = in.slice(); byte[] bytes = new byte[buf.limit()]; buf.get(bytes); String str = new String(bytes); output.write(str); in.position(curPosition); in.limit(limit); return true; } } // , in.position(startPosition); return false; } }

MyProtocolCodecFactory :
package com.socket.r1;

import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFactory;
import org.apache.mina.filter.codec.ProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolEncoder;

public class MyProtocolCodecFactory implements ProtocolCodecFactory {

//  private MyDecoder decoder;
    private MyCumulativeDecoder decoder;
    private MyEncoder encoder;

    public MyProtocolCodecFactory() {
//      decoder = new MyDecoder();
        decoder = new MyCumulativeDecoder();
        encoder = new MyEncoder();
    }

    public ProtocolDecoder getDecoder(IoSession arg0) throws Exception {
        return decoder;
    }

    public ProtocolEncoder getEncoder(IoSession arg0) throws Exception {
        return encoder;
    }

}

좋은 웹페이지 즐겨찾기