Socket通信是Java网络编程中比较基础的部分,其原理其实就是源ip,源端口和目的ip,目的端口组成的套接字通信。其底层还设及到了TCP协议的通信。

Java中的Socket通信可以通过客户端的Socket与服务端的ServerSocket通信,同时利用IO流传递数据,也就是说Socket通信是面向流的使用的是BIO,并不同于后来的NIO通信面向缓冲。Socket通信中使用的IO流的read,readline等函数都是阻塞的,这就导致了在通信过程中,双方不能确定什么时侯是流的结束,针对这种可以通过约定结束符的方式进行结束,也可以约定一次传输的字节流的长度。下面通过代码进行说明

客户端

建立客户端线程,在run方法中不断对服务端进行发送消息,模拟多个客户端的通信,通过写入换行符,表明这次通信的结束。

 1 class Client implements Runnable {
2
3 private byte[] targetIp;
4 private int port;
5
6 Client(byte[] ip, int port) {
7 this.targetIp = ip;
8 this.port = port;
9 }
10
11 @Override
12 public void run() {
13 try {
14 InetAddress inetAddress = InetAddress.getByAddress(targetIp);
15 Socket socket = new Socket(inetAddress, port);
16 System.out.println("client");
17 BufferedReader socketInput = new BufferedReader(new InputStreamReader(socket.getInputStream()));
18 BufferedWriter socketOutput = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
19
20 int i = 0;
21 String NAME = "Client";
22 while (true) {
23 socketOutput.write("This msg from " + NAME + " msg id is " + i);
24 socketOutput.write("\n");//约定结束符表示流的结束
25 i++;
26 socketOutput.flush();
27 System.out.println("here");
28 String str = null;
29 if (!(str = socketInput.readLine()).equals("\n")) {
30 System.out.println(str);
31 }
32
33 }
34
35 /*socket.shutdownInput();
36 socket.shutdownOutput();*/
37 } catch (IOException e) {
38 e.printStackTrace();
39 }
40
41 }
42 }

服务端

服务端通过accept接受客户端的连接,这个操作是阻塞的,直到有客户端的连接才能进行下一步。

 1 class Server implements Runnable {
2
3 private int port;
4
5 Server(int port) {
6 this.port = port;
7 }
8 @Override
9 public void run() {
10 try {
11 ServerSocket serverSocket = new ServerSocket(port);
12
13 InetAddress inetAddress = serverSocket.getInetAddress();
14 System.out.println("server" + inetAddress.getHostAddress());
15 Socket socket = serverSocket.accept();
16 BufferedReader socketInput = new BufferedReader(new InputStreamReader(socket.getInputStream()));
17 BufferedWriter socketOutput = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
18
19 int i = 0;
20 while (true) {
21 String str = null;
22 if (!(str = socketInput.readLine()).equals("\n")) System.out.println(str);
23 System.out.println("server");
24
25 String NAME = "Server";
26 socketOutput.write("This msg from " + NAME + " msg num is " + i + " reply to " + str);
27 socketOutput.write("\n");
28 i++;
29 socketOutput.flush();
30 }
31
32 // socket.shutdownInput();
33 // socket.shutdownOutput();
34 } catch (IOException e) {
35 e.printStackTrace();
36 }
37
38 }
39 }

测试

 1 public class SocketTest {
2 public static void main(String[] args) {
3 byte[] ip = {127, 0, 0, 1};
4 int port = 27149;
5 Thread server = new Thread(new Server(port), "server");
6 server.start();
7 Thread client = new Thread(new Client(new byte[]{0,0,0,0}, 27149));
8 client.start();
9 }
10 }

结果

服务端针对客户端的每条信息都能够进行读取并返回消息给客户端,但是如果注释掉写入换行符,并判断读取是否是换行符的代码,就无法读取到流的结束。

【Java】Java socket通信使用read,readline函数的阻塞问题的更多相关文章

  1. Flex通信-与Java实现Socket通信实例

    Flex通信-与Java实现Socket通信实例  转自:http://blessht.iteye.com/blog/1136888 博客分类: Flex 环境准备 [服务器端] JDK1.6,“ja ...

  2. java的socket通信

    本文讲解如何用java实现网络通信,是一个非常简单的例子,我比较喜欢能够立马看到结果,所以先上代码再讲解具体细节. 服务端: import java.io.BufferedReader; import ...

  3. Java的Socket通信----通过 Socket 实现 TCP 编程之多线程demo(2)

    JAVA Socket简介 所谓socket 通常也称作”套接字“,用于描述IP地址和端口,是一个通信链的句柄.应用程序通常通过”套接字”向网络发出请求或者应答网络请求. import java.io ...

  4. Java的Socket通信简单实例

    服务端 package testlxd; import java.io.BufferedReader; import java.io.IOException; import java.io.Input ...

  5. C++服务器与java进行socket通信案例

    分类: [java]2012-10-08 12:03 14539人阅读 评论(46) 收藏 举报 注:本代码版权所有!!!转载时请声明源地址:http://blog.csdn.net/nuptboyz ...

  6. Java:Socket通信

    Socket通常也称作"套接字".用于描写叙述IP地址和port,是一个通信链的句柄.应用程序通常通过"套接字"向网络发出请求或者应答网络请求. ServerS ...

  7. java的Socket通信例子及关于java.net.SocketException: Socket is closed错误

    今天写socket数据相互通信的时候,碰到一个及其蛋疼的错误.单向传输数据的时候server与client是没有问题的,但是两个都有输入输出操作的时候就出现了这个问题 java.net.SocketE ...

  8. java NIO socket 通信实例

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/zhuyijian135757/article/details/37672151 java Nio 通 ...

  9. Java实现Socket通信

    一对一通信: 服务器端: public class ServerDemo { public static void main(String[] args) { ServerSocket serverS ...

随机推荐

  1. linux下生成动态库和链接动态库

    1.生成动态库 src/test.h #ifndef _TEST_H_HH #define _TEST_H_HH void print(); #endif src/test.cpp #include ...

  2. Hadoop基础------>MR框架-->WordCount

    认识Mapreduce Mapreduce编程思想 Mapreduce执行流程 java版本WordCount实例 1. 简介: Mapreduce源于Google一遍论文,是谷歌Mapreduce的 ...

  3. PHP获取网站中文章的第一张图片作为缩略图的方法

    调取文章中的第一张图作为列表页缩略图是很流行的做法,WordPress中一般主题默认也是如此,那我们接下来就一起来看看PHP获取网站中各文章的第一张图片的代码示例 $temp=mt_rand(1,4) ...

  4. git/SQL/正则表达式的在线练习网站

    虽说我没事就喜欢喷应试教育,但我也从应试教育中发现了一个窍门:如果能够以刷题的形式学习某项技能,效率和效果是最佳的.对于技术的学习,我经常面临的困境是,理论知识知道的不少,但是有的场景实在无法模拟,缺 ...

  5. CSS取消鼠标点击事件

    pointer-events: none; 大致意思是让鼠标失去事件, 就比如我的'血小板'看板上的那个提示, 可以按F12来查看.

  6. Docker(6)- docker info 命令详解

    如果你还想从头学起 Docker,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1870863.html 作用 显示 Docker 系统信 ...

  7. 配置交换机Trunk接口流量本地优先转发(集群/堆叠)

    组网图形 Eth-Trunk接口流量本地优先转发简介 在设备集群/堆叠情况下,为了保证流量的可靠传输,流量的出接口设置为Eth-Trunk接口.那么Eth-Trunk接口中必定存在跨框成员口.当集群/ ...

  8. SpringBoot入门最简单的一个项目示例

    使用IDEA创建一个SpringBoot项目 1.1 打开IDEA,文件-New-Project 1.2下一步,选择版本8(根据自己安装的JDK版本来选择) 1.3 下一步后点击Web,勾选Sprin ...

  9. C# 集合类(三)

    C# 集合类自己经常用到: 数组(Array).动态数组(ArrayList).列表(List).哈希表(Hashtable).字典(Dictionary),对于经常使用的这些数据结构,做一个总结,便 ...

  10. 自定义MFC对话窗口的类名

    默认情况下,MFC对话框的窗口类名为"#32770",如果想自定义窗口类名呢,需要两步: 1.修改rc文件 这一步需要直接编辑rc文件,使用任意记事本工具即可,找到窗口的相关定义, ...