读书人

学习Mina2(学识准备 - socket - 1)

发布时间: 2013-03-14 10:33:15 作者: rapoo

学习Mina2(知识准备 - socket - 1)
做Java编程这么多年了,今天学习mina框架的时候,确发现自己连socket编程都不太了解,真是愧对这几年的Java学习经验了。所以在学习mina2前,我首选尝试者了解一下socket。

1. 先摸索个例子程序

实现功能概述:客户端向服务端发送一个命令,服务端接受,并发消息给客户端证明已经收到。如果输入“end”(不区分大小写)测试结束。

1.1 socket服务端

public class CmdServer {public static final Log LOG = LogFactory.getLog(CmdServer.class);public static final int SERVER_PROT = 8100;private static final CmdServer cmdServer = new CmdServer();private ServerSocket server;private CmdServer() {try {server = new ServerSocket(SERVER_PROT);}catch (IOException e) {throw new RuntimeException(e.getMessage(), e.getCause());}}public static CmdServer getServer() {return cmdServer;}public void receiveCmd() {LOG.info(">>>接受命令开始...");BufferedReader reader = null;PrintWriter writer = null;try {Socket client = server.accept();reader = new BufferedReader(new InputStreamReader(client.getInputStream()));writer = new PrintWriter(client.getOutputStream());while (true) {String cmd = reader.readLine();writer.print("roger : " + cmd + "\n");LOG.info("roger : " + cmd);writer.flush();if (StringUtils.endsWithIgnoreCase("end", cmd)) {break;}}client.close();}catch (IOException e) {LOG.error(e.getMessage(), e);throw new RuntimeException(e.getMessage(), e.getCause());}finally {IOUtils.closeQuietly(reader);IOUtils.closeQuietly(writer);}LOG.info("<<<接受命令结束");}}public class RunSocketServer {public static void main(String[] args) {CmdServer server = CmdServer.getServer();server.receiveCmd();}}

1.2 socket客户端
public class CmdClient {public static final Log LOG = LogFactory.getLog(CmdClient.class);private Socket server;public CmdClient() {try {server = new Socket(InetAddress.getLocalHost(), CmdServer.SERVER_PROT);}catch (Exception e) {throw new RuntimeException(e.getMessage(), e.getCause());}}public void writeCmd() {LOG.info(">>>写命令开始...");Scanner scanner = new Scanner(System.in);BufferedReader reader = null;BufferedWriter writer = null;try {reader = new BufferedReader(new InputStreamReader(server.getInputStream()));writer = new BufferedWriter(new OutputStreamWriter(server.getOutputStream()));while (true) {String cmd = scanner.nextLine();LOG.info("input:" + cmd);writer.write(cmd + "\n");writer.flush();if (StringUtils.endsWithIgnoreCase("end", cmd)) {break;}LOG.info(reader.readLine());}server.close();}catch (Exception e) {LOG.error(e.getMessage(), e);throw new RuntimeException(e.getMessage(), e.getCause());}finally {scanner.close();IOUtils.closeQuietly(reader);IOUtils.closeQuietly(writer);}LOG.info(">>>写命令结束");}}public class RunSocketClient {public static void main(String[] args) {CmdClient client = new CmdClient();client.writeCmd();}}


2 总结
这么简单的一个程序,需要多久才能够调通呢?对我这样的菜鸟来说折腾了很久。

2.1 遇到的问题和解决方法
感觉只能从客户端写一行字符串,然后程序就戛然而止首选我怀疑是用控制台输入的问题,开始使用的是System.in来包装BufferedReader,所以就查了一些资料,发现可以在JDK5下面可以使用Scanner scanner = new Scanner(System.in);(参考http://www.mkyong.com/java/how-to-read-input-from-console-java/)。使用原始的bufferReader时无法循环的读取输入。 终于可以多行了,但是服务器端不是实时接收到的,只有调用close的时候才收到发现当客户端程序运行到LOG.info(reader.readLine());时,就运行不下去了。
于是注释这句试试,发现可以运行,但是服务器端貌似不是实时的输出,开始怀疑是socket缓存的问题(参考http://blog.sina.com.cn/s/blog_616e189f0100s3px.html)。但是无论我怎么调整服务器端和客户端的缓存的大小,都是无法解决。
最后发现是程序是读取一行的,但是我写入数据的时候没有分行符"\n"导致的。加上分行符,问题解决了

2.2 学习到了什么?
认识了什么是Socket,以及socket的基本实现 认识了socket中还有缓存需要注意的地方 了解了从控制台中读取输入的另外一种方法
3. 下面我们会干点什么?
上面的程序只能连接一次,服务就关闭了,应该改进一下 多个客户端连接到服务器端,怎么交互呢

读书人网 >编程

热点推荐