使用jdk的socket通信
来源:互联网 发布:javascript库 知乎 编辑:程序博客网 时间:2024/05/01 16:26
使用JDK提供的API进行网络通信,会用到Socket,ServerSocket两个类。写个简单的SERVER和CLIENT之间发消息的小程序,竟然发现了挺多的问题。
这是服务器端代码:
package org.chat;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.ServerSocket;import java.net.Socket;public class ChatServer {public static void main(String[] args) {ChatServer server = new ChatServer();server.start();}public void start() {while (true) {ServerSocket s = null;Socket socket = null;try {s = new ServerSocket(10001);socket = s.accept();BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));PrintWriter out = new PrintWriter(socket.getOutputStream(),true);String content = in.readLine();System.out.println(content);content = content + "1";out.print(content);out.flush(); // if not flush, client can't receive datain.close();out.close();} catch (IOException e) {e.printStackTrace();} finally{try {s.close();socket.close();} catch (IOException e) {e.printStackTrace();}}}}}
这是客户端代码:
package org.chat;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.Socket;import java.net.UnknownHostException;public class Client {public static void main(String[] args) {Socket socket = null;try {socket = new Socket("128.192.184.93", 10001);BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));PrintWriter out = new PrintWriter(socket.getOutputStream(), true);out.println("hello");String reply = in.readLine();System.out.println(reply);in.close();out.close();} catch (UnknownHostException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally{try {socket.close();} catch (IOException e) {e.printStackTrace();}}}}
逻辑很简单:Client会向ChatServer发一个字符串"hello",ChatServer收到后,在这个字符串后面加1,然后发给Client。
这其中遇到了几个问题:
1.PrintWriter构造函数参数autoFlush设置
PrintWriter的构造函数里的第二个参数autoFlush,API文档里解释是:if true, the println,printf, or format methods will flush the output buffer。注意不包括print。
因此,对于ChatServer,32,33行(print),如果不调用flush,Client就收不到数据,尽管在PrintWriter的构造函数里,autoFlush=true;而Client的19行(println),无需调用flush,也能发送数据。
2.Socket的InputStream和OutputStream有关联,如果一个在用,另一个不可关闭
在ChatServer中,如果把35行代码in.close()放到29行之后,30行之前,也就是说,in在读取了数据之后,就关闭掉,造成的后果就是32行代码out.print()失效,这是因为in.close()使socket关闭了,Client只能收到一个null
3.BufferReader的readLine()方法
首先,该方法是阻塞的,如果读不到(即使读到null也算读到),就会阻塞。
该方法会读取一行数据,就是说,读取第一个换行符之前的数据,如果发送的数据中没有换行符,那么,readLine可能会阻塞。
PrintWriter.print()发送的数据中没有换行符,所以多次调用,接受方BufferReader.readLine()一次接受多次print的数据。
- 使用jdk的socket通信
- 使用WSAAsyncSelect的Socket通信
- 使用非阻塞方式的Socket通信
- 使用socket的阻塞简单通信聊天工具
- Android中socket通信的简单使用
- redis的php类-使用socket通信
- 使用Socket进行通信
- 使用Socket进行通信
- socket通信之socket的通信过程
- 使用socket连接实现客户端向服务器端的单向通信(socket通信第二弹)
- 简单的SOCKET通信
- socket 的通信过程
- Socket通信的常识、、
- socket 的通信过程
- 简单的Socket通信
- flex的Socket通信
- php的socket通信
- socket通信的基本原理
- C#编写ActiveX控件
- 总结:复合数据对象
- <转>c#调用C++DLL类型转换
- BufferedReader readline() method dosen't read "\n".
- Ubuntu12.04下用bash操作mysql
- 使用jdk的socket通信
- Android学习笔记
- 用EditPlus查看或修改文件编码的方法
- [翻译]实例:在Android调用WCF服务
- 聚类1
- 如何保证数据库结构的合理性(一、调整字段)
- 前缀,中缀,后缀表达式
- arcgis10.1如何生成MSD记录
- 海量数据面试题举例