Socket 프로그래밍 및mina 프레임워크 간단한 예
36889 단어 java 네트워크 프로그래밍 관련
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;
}
}