参考资料:java核心技术 卷II

为中断套接字操作,可使用java.nio包提供的SocketChannel类。可以使用如下方式打开SocketChannel:

SocketChannel channel = SocketChannel.open(new InetSocketAddress(host, port));

java实现如下:

public class InterruptibleSocketTest {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable()
{
public void run(){
JFrame frame=new InterruptibleSocketFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true); //显示此窗体 }
});
}
}
class InterruptibleSocketFrame extends JFrame{
//private static final long serialVersionUID = 1L;
public InterruptibleSocketFrame(){
setSize(WIDTH,HEIGHT);//设置窗体大小
setTitle("InterruptibleSocketTest"); JPanel northpJPanel =new JPanel();
add(northpJPanel,BorderLayout.NORTH);//对容器进行定位 messages=new JTextArea(); //JTextArea类,是一个显示纯文本的多行区域
add(new JScrollPane(messages)); //JScrollPane类,为数据源提供一个窗口
interruptilButton=new JButton("Interruptilbel");//JButton类,按钮
blockingButton=new JButton("Blocking"); northpJPanel.add(interruptilButton);//将button添加到窗口中
northpJPanel.add(blockingButton); interruptilButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event){
interruptilButton.setEnabled(false);
blockingButton.setEnabled(false);//blocking按钮变成不可用
cancelButton.setEnabled(true); //cancelButton按钮变成可用
connectThread=new Thread(new Runnable(){//创建新线程
public void run() {
try{
connectInterruptibly();
} catch (Exception e) {
messages.append("\nInterruptibleSocketTest.connectInterruptibly: "+e);
}
}
});
connectThread.start();
}
});
blockingButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
interruptilButton.setEnabled(false);
blockingButton.setEnabled(false);
cancelButton.setEnabled(true);
connectThread=new Thread(new Runnable(){
public void run() {
try {
connectBlocking();
} catch (IOException e) {
messages.append("\nInterruptibleSocketTest.connectblocking: "+e);
}
}
});
connectThread.start();
}
}); cancelButton =new JButton("Cancel");
cancelButton.setEnabled(false);
northpJPanel.add(cancelButton);
cancelButton.addActionListener(new ActionListener() {//点击cancel按钮来中断线程
public void actionPerformed(ActionEvent e) {
connectThread.interrupt();
cancelButton.setEnabled(false); }
});
server =new TestServer(); //自定义的TestServer类
new Thread(server).start(); }
/**
* 连接到测试服务器,使用可中断I/O
*/
public void connectInterruptibly() throws IOException{
messages.append("Interruptible:\n");
SocketChannel channel=SocketChannel.open(new InetSocketAddress("localhost", 8189));//可中断套接字
try {
in=new Scanner(channel);
while(!Thread.currentThread().isInterrupted()){
messages.append("Reading ");
if(in.hasNextLine()){//获取服务器的输出
String line=in.nextLine();
messages.append(line);
messages.append("\n");
}
}
}finally{
channel.close();
EventQueue.invokeLater(new Runnable() {
public void run() {
messages.append("Channel closed\n");
interruptilButton.setEnabled(true);
blockingButton.setEnabled(true);
}
});
}
}
/**
* 连接到测试服务器,使用阻塞I/O
*/
public void connectBlocking() throws IOException{
messages.append("Blocking:\n");
Socket socket=new Socket("localhost",8189); //不可中断套接字
try {
in=new Scanner(socket.getInputStream());
while (!Thread.currentThread().isInterrupted()){
messages.append("Reading ");
if(in.hasNextLine()){
String line=in.nextLine();
messages.append(line);
messages.append("\n");
}
}
}finally{
socket.close();
EventQueue.invokeLater(new Runnable() {
public void run() {
messages.append("Socket closed\n");
interruptilButton.setEnabled(true);
blockingButton.setEnabled(true);
}
});
}
}
/**
* 一个监听8189端口的多线程服务器,并向客户端连续发送数字,并在发送10个数字之后挂起
*/
class TestServer implements Runnable{
public void run() {
try {
ServerSocket s=new ServerSocket(8189);
while(true){
Socket incoming=s.accept();
Runnable r=new TestServerHandler(incoming);
Thread t=new Thread(r);
t.start();
}
} catch (Exception e) {
messages.append("\nTestServer.run: "+e);
}
} }
/**
* 处理客户端用于服务器套接字链接的客户端输入
*/
class TestServerHandler implements Runnable{
public TestServerHandler(Socket i){
incoming=i;
}
public void run() {
try {
OutputStream outputStream=incoming.getOutputStream();
PrintWriter out=new PrintWriter(outputStream,true /*autoFulsh*/);
while(counter < 100){
counter++;
if(counter <= 10)
out.println(counter);
Thread.sleep(100);
}
incoming.close();
messages.append("Closing Server\n");
} catch (Exception e) {
messages.append("\nTestServerHandler.run: "+e);
} }
private Socket incoming;
private int counter;
} private Scanner in;
private JTextArea messages;
private JButton interruptilButton,blockingButton,cancelButton;
private Thread connectThread;
private TestServer server; public static final int WIDTH=550;
public static final int HEIGHT=400;
}

执行程序,点击Blocking,在第一批的10个数字执行过程中,点击cancel,仍会继续输完10个数字,Interruptible和Blocking两个按钮变不可用。点击Interruptible可中断线程。

java网络编程(二)可中断套接字的更多相关文章

  1. [转载] 读《UNIX网络编程 卷1:套接字联网API》

    原文: http://cstdlib.com/tech/2014/10/09/read-unix-network-programming-1/ 文章写的很清楚, 适合初学者 最近看了<UNIX网 ...

  2. 网络编程基础之Socket套接字

    一.Socket介绍 1.什么是socket? Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族 ...

  3. 网络编程基础之Socket套接字简单应用

    一.Socket套接字实现通信循环 所谓通信循环,简单理解就是客户端可以给服务端循环发送信息并获得反馈的过程. 1.基础版 通信循环的程序分为两部分,即两个python模块,分别为客户端.py和服务端 ...

  4. Java网络编程二:Socket详解

    Socket又称套接字,是连接运行在网络上两个程序间的双向通讯的端点. 一.使用Socket进行网络通信的过程 服务端:服务器程序将一个套接字绑定到一个特定的端口,并通过此套接字等待和监听客户端的连接 ...

  5. 网络编程初识和socket套接字

    网络的产生 不同机器上的程序要通信,才产生了网络:凡是涉及到倆个程序之间通讯的都需要用到网络 软件开发架构 软件开发架构的类型:应用类.web类 应用类:qq.微信.网盘.优酷这一类是属于需要安装的桌 ...

  6. 网络编程(socket,套接字)

    服务端地址不变 ip + mac 标识唯一一台机器 ip +端口 标识唯一客户端应用程序 套接字: 网络编程   网络编程 一.python提供了两个级别访问的网络服务 低级别的网络服务支持基本的 S ...

  7. UNIX网络编程——使用select 实现套接字I/O超时

    下面程序包含read_timeout.write_timeout.accept_timeout.connect_timeout 四个函数封装: /* read_timeout - 读超时检测函数,不含 ...

  8. UNIX 网络编程笔记-CH3:套接字编程简介

    IPv4套接字地址结构 struct in_addr { in_addr_t s_addr; }; struct sockaddr_in { uint8_t sin_len; /* length of ...

  9. 《Unix网络编程卷1:套接字联网API》读书笔记

    第一部分:简介和TCP/IP 第1章:简介 第2章:传输层:TCP.UDP和SCTP TCP:传输控制协议,复杂.可靠.面向连接协议 UDP:用户数据报协议,简单.不可靠.无连接协议 SCTP:流控制 ...

  10. 【TCP/IP网络编程】:09套接字的多种可选项

    本篇文章主要介绍了套接字的几个常用配置选项,包括SO_SNDBUF & SO_RCVBUF.SO_REUSEADDR及TCP_NODELAY等. 套接字可选项和I/O缓冲大小 前文关于套接字的 ...

随机推荐

  1. 2017-2018-1 20155338《信息安全技术》实验二——Windows口令破解

    2017-2018-1 20155338<信息安全技术>实验二--Windows口令破解 一.试验环境 系统环境:Windows 实验工具: LC5 SuperDic 二.实验内容及要求 ...

  2. underscore.js 分析 第三天

    // Create a safe reference to the Underscore object for use below. // 为Underscore对象创建一个安全的引用 // _为一个 ...

  3. Spring学习(五)-----注入bean属性的三种方式( 1: 正常的方式 2: 快捷方式 3: “p” 模式)

    在Spring中,有三种方式注入值到 bean 属性. 正常的方式 快捷方式 “p” 模式 看到一个简单的Java类,它包含两个属性 - name 和 type.稍后将使用Spring注入值到这个 b ...

  4. node升级7.0以上版本使用gulp时报错

    今天使用gulp时 ,出现了以下报错信息: Error: Cannot find module 'internal/fs'at Object.<anonymous> (/home/XXX/ ...

  5. Python爬虫下载Bilibili番剧弹幕

    本文绍如何利用python爬虫下载bilibili番剧弹幕. 准备: python3环境 需要安装BeautifulSoup,selenium包 phantomjs 原理: 通过aid下载bilibi ...

  6. Qt creator 最常用的13个快捷键

    alt +enter // 自动创建类的定义 F1 // 查看帮助,文档 F2 // 快速到变量声明 Shift + F2 // 函数的声明和定义之间快速切换 F4 // 在 cpp 和 h 文件切换 ...

  7. CSP201609-2:火车购票

    引言:CSP(http://www.cspro.org/lead/application/ccf/login.jsp)是由中国计算机学会(CCF)发起的"计算机职业资格认证"考试, ...

  8. SVN部署与简单使用

    原文发表于cu:2016-05-24 参考文档: http://www.tuicool.com/articles/Yv2iyu7 http://www.centoscn.com/CentosServe ...

  9. 使用JS验证文件类型

    项目中涉及到这一需求,在此贴出代码分享给大家, 有2中方式,一种是input中使用accept 方式 一种是使用js正则表达式判断,个人推荐使用js正则表达式,因为accept 有的浏览器并不支持,而 ...

  10. 微信小程序-----自定义验证码实现

    这一段时间做小程序项目,使用的是mpvue的框架,需要自己实现验证码输入,模拟input的光标,上一个框输入后后一个框自动获取焦点,删除时从后往前依次删除.下图是整体效果: <template& ...