java网络编程(二)可中断套接字
参考资料: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网络编程(二)可中断套接字的更多相关文章
- [转载] 读《UNIX网络编程 卷1:套接字联网API》
原文: http://cstdlib.com/tech/2014/10/09/read-unix-network-programming-1/ 文章写的很清楚, 适合初学者 最近看了<UNIX网 ...
- 网络编程基础之Socket套接字
一.Socket介绍 1.什么是socket? Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族 ...
- 网络编程基础之Socket套接字简单应用
一.Socket套接字实现通信循环 所谓通信循环,简单理解就是客户端可以给服务端循环发送信息并获得反馈的过程. 1.基础版 通信循环的程序分为两部分,即两个python模块,分别为客户端.py和服务端 ...
- Java网络编程二:Socket详解
Socket又称套接字,是连接运行在网络上两个程序间的双向通讯的端点. 一.使用Socket进行网络通信的过程 服务端:服务器程序将一个套接字绑定到一个特定的端口,并通过此套接字等待和监听客户端的连接 ...
- 网络编程初识和socket套接字
网络的产生 不同机器上的程序要通信,才产生了网络:凡是涉及到倆个程序之间通讯的都需要用到网络 软件开发架构 软件开发架构的类型:应用类.web类 应用类:qq.微信.网盘.优酷这一类是属于需要安装的桌 ...
- 网络编程(socket,套接字)
服务端地址不变 ip + mac 标识唯一一台机器 ip +端口 标识唯一客户端应用程序 套接字: 网络编程 网络编程 一.python提供了两个级别访问的网络服务 低级别的网络服务支持基本的 S ...
- UNIX网络编程——使用select 实现套接字I/O超时
下面程序包含read_timeout.write_timeout.accept_timeout.connect_timeout 四个函数封装: /* read_timeout - 读超时检测函数,不含 ...
- UNIX 网络编程笔记-CH3:套接字编程简介
IPv4套接字地址结构 struct in_addr { in_addr_t s_addr; }; struct sockaddr_in { uint8_t sin_len; /* length of ...
- 《Unix网络编程卷1:套接字联网API》读书笔记
第一部分:简介和TCP/IP 第1章:简介 第2章:传输层:TCP.UDP和SCTP TCP:传输控制协议,复杂.可靠.面向连接协议 UDP:用户数据报协议,简单.不可靠.无连接协议 SCTP:流控制 ...
- 【TCP/IP网络编程】:09套接字的多种可选项
本篇文章主要介绍了套接字的几个常用配置选项,包括SO_SNDBUF & SO_RCVBUF.SO_REUSEADDR及TCP_NODELAY等. 套接字可选项和I/O缓冲大小 前文关于套接字的 ...
随机推荐
- VS2010 不显示 最近使用的项目 解决办法
昨天重装了VS2010,然后开了项目看了下今天早上再打开发现起始页近使用项目列表是空白的,每次打开项目都要去到指定目录去找解决方案才能打开,感觉很麻烦,在网上找了下解决方案,解决步骤下:菜单 —— 运 ...
- C#之Lambda不得不说的用法
由于我才开始接触代码的时候遇到循环问题都是用foreach和for,慢慢就成了习惯,不愿意用其他简便的方式,偶然发现lambda能代替循环而且简便了很多.当然我用lambda也不是简便,更多是不用不行 ...
- 【C#利用后台动态加载数据】Winform“防界面卡死”【BackgroundWorker】类
using System.ComponentModel 直接使用EgProgressBar方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 2 ...
- hdu2187悼念512汶川大地震遇难同胞——老人是真饿了(贪心 简单题)
传送门 简单题 #include<bits/stdc++.h> using namespace std; struct node { double dan,weight; }a[]; bo ...
- git拉代码,IntelliJ idea报错,cannot load module xxxxx
1 从git上下工程的时候,IntelliJ idea报错,cannot load module xxxx VCS-git-clone-ssh:xxxx ,报错cannot load module x ...
- 05-Docker架构详解
Docker 的核心组件包括: Docker 客户端 - Client Docker 服务器 - Docker daemon Docker 镜像 - Image Registry Docker 容器 ...
- 人脸检测及识别python实现系列(6)——终篇:从实时视频流识别出“我”
人脸检测及识别python实现系列(6)——终篇:从实时视频流识别出“我” 终于到了最后一步,激动时刻就要来临了,先平复一下心情,把剩下的代码加上,首先是为Model类增加一个预测函数: #识别人脸 ...
- Python Web部署方式全汇总
学过PHP的都了解,php的正式环境部署非常简单,改几个文件就OK,用FastCgi方式也是分分钟的事情.相比起来,Python在web应用上的部署就繁杂的多,主要是工具繁多,主流服务器支持不足. 在 ...
- CentOS7.x安装Docker1.11.1
原文发表于cu:2016-05-30 本文属于重发,当前Docker已经分为EE与CE版本,CE版本是17.06.0-ce,最新的CE版本安装方式已略有不同:但可以指定安装版本,如1.11.1,1.1 ...
- Halcon如何保存仿射变换矩阵
这里我们通过序列化来实现的,如下图,写到硬盘的HomMat2D_1内容和从硬盘里HomMat2D_2读出的内容一致,源代码在图片下方. Halcon源代码: hom_mat2d_identity (H ...