반응형
공감 및 댓글은 포스팅 하는데 아주아주 큰 힘이 됩니다!! 포스팅 내용이 찾아주신 분들께 도움이 되길 바라며 더 깔끔하고 좋은 포스팅을 만들어 나가겠습니다^^
|
Netty socket Server and android client socket communication
지난 포스팅까지해서
네티 채팅 서버/클라이언트를 만들어서, 이크립스 콘솔에서 채팅하는 기능을 만들어보았는데요.
클라이언트를 안드로이드 쪽으로 와서 같은 기능으로 구현해보았습니다.
서버는
2017/12/13 - [Netty(네티)] - Netty(네티) 채팅 서버/클라이언트 [1] : 채팅 서버 만들기
여기서 조금 수정되었습니다.
ChatServerInitializer.java 파일이 수정되었는데요.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | import java.util.List; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.ByteToMessageDecoder; import io.netty.handler.codec.DelimiterBasedFrameDecoder; import io.netty.handler.codec.Delimiters; import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.codec.string.StringEncoder; import io.netty.handler.ssl.SslContext; public class ChatServerInitializer extends ChannelInitializer<SocketChannel> { private final SslContext sslCtx; public ChatServerInitializer(SslContext sslCtx) { this.sslCtx = sslCtx; } @Override protected void initChannel(SocketChannel arg0) throws Exception { ChannelPipeline pipeline = arg0.pipeline(); //pipeline.addLast(sslCtx.newHandler(arg0.alloc())); //pipeline.addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter())); pipeline.addLast(new ByteToMessageDecoder() { @Override public void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception { out.add(in.readBytes(in.readableBytes())); } }); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); pipeline.addLast(new ChatServerHandler()); } } | cs |
//pipeline.addLast(new DelimiterBasedFrameDecoder(...); 을 주석처리하고,
pileline.addLast(new ByteToMessageDecoder() {
@Override
public void decode(...) {
}
}); 로 대체하였습니다.
기존 코드를 사용하게 되면 안드로이드에서 보내는 메시지를 서버에서
언제 출력해 줄지를 알 수가 없어서 정상적으로 동작을 하지 않습니다.
다음은 안드로이드 코드입니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | public class MainActivity extends AppCompatActivity { Handler handler; String data; SocketChannel socketChannel; private static final String HOST = "접속할 네티서버 IP"; private static final int PORT = 5001; String msg; ActivityMainBinding binding; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = DataBindingUtil.setContentView(this, R.layout.activity_main); handler = new Handler(); new Thread(new Runnable() { @Override public void run() { try { socketChannel = SocketChannel.open(); socketChannel.configureBlocking(true); socketChannel.connect(new InetSocketAddress(HOST, PORT)); } catch (Exception ioe) { Log.d("asd", ioe.getMessage() + "a"); ioe.printStackTrace(); } checkUpdate.start(); } }).start(); binding.sendMsgBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try { final String return_msg = binding.sendMsgEditText.getText().toString(); if (!TextUtils.isEmpty(return_msg)) { new SendmsgTask().execute(return_msg); } } catch (Exception e) { e.printStackTrace(); } } }); } private class SendmsgTask extends AsyncTask<String, Void, Void> { @Override protected Void doInBackground(String... strings) { try { socketChannel .socket() .getOutputStream() .write(strings[0].getBytes("EUC-KR")); // 서버로 } catch (IOException e) { e.printStackTrace(); } return null; } @Override protected void onPreExecute() { super.onPreExecute(); runOnUiThread(new Runnable() { @Override public void run() { binding.sendMsgEditText.setText(""); } }); } } void receive() { while (true) { try { ByteBuffer byteBuffer = ByteBuffer.allocate(256); //서버가 비정상적으로 종료했을 경우 IOException 발생 int readByteCount = socketChannel.read(byteBuffer); //데이터받기 Log.d("readByteCount", readByteCount + ""); //서버가 정상적으로 Socket의 close()를 호출했을 경우 if (readByteCount == -1) { throw new IOException(); } byteBuffer.flip(); // 문자열로 변환 Charset charset = Charset.forName("EUC-KR"); data = charset.decode(byteBuffer).toString(); Log.d("receive", "msg :" + data); handler.post(showUpdate); } catch (IOException e) { Log.d("getMsg", e.getMessage() + ""); try { socketChannel.close(); break; } catch (IOException ee) { ee.printStackTrace(); } } } } private Thread checkUpdate = new Thread() { public void run() { try { String line; receive(); } catch (Exception e) { e.printStackTrace(); } } }; private Runnable showUpdate = new Runnable() { public void run() { String receive = "Coming word : " + data; binding.receiveMsgTv.setText(receive); } }; @Override protected void onDestroy() { super.onDestroy(); try { socketChannel.close(); } catch (Exception e) { e.printStackTrace(); } } } | cs |
두 대의 에뮬레이터를 실행시키고 해보시면 정상 동작할 거에요 ^^
layout은 각 자 편하신 대로 만드시면 됩니닷 ^^
이상입니다.
감사합니다.
반응형
'Netty(네티)' 카테고리의 다른 글
Netty 네티의 장점[1] : 블로킹과 논블로킹 변경을 간편하게. (0) | 2017.12.19 |
---|---|
네티 - 이클립스 자바 프로젝트에 네티 라이브러리 추가 및 Source Attachment (0) | 2017.12.15 |
Netty(네티) 채팅 서버/클라이언트 [2] : 채팅 클라이언트 만들기 (1) | 2017.12.13 |
Netty(네티) 채팅 서버/클라이언트 [1] : 채팅 서버 만들기 (2) | 2017.12.13 |
Netty(네티) 채팅 서버/클라이언트에 사용되는 클래스 알아보기! (0) | 2017.12.12 |