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缓冲大小 前文关于套接字的 ...
随机推荐
- 20155339 2016-2017-2 《Java程序设计》第4周学习总结
20155339 2016-2017-2 <Java程序设计>第4周学习总结 教材学习内容总结 继承.多态与is-a 继承就是避免多个类间重复定义共同行为. 可以把相同的成粗代码提升为父类 ...
- Qt QStringLiteral
zz 解释QStringLiteral 原文发表于woboq网站 QStringLiteral explained 转载 原作者: Olivier Goffart 译者:zzjin QStringL ...
- 【BZOJ2754】[SCOI2012]喵星球上的点名
[BZOJ2754][SCOI2012]喵星球上的点名 题面 bzoj 洛谷 题解 这题有各种神仙做法啊,什么暴力\(AC\)自动机.\(SAM\)等等五花八门 我这个蒟蒻在这里提供一种复杂度正确且常 ...
- LOJ #2585. 「APIO2018」新家
#2585. 「APIO2018」新家 https://loj.ac/problem/2585 分析: 线段树+二分. 首先看怎样数颜色,正常的时候,离线扫一遍右端点,每次只记录最右边的点,然后查询左 ...
- zedboard学习(1)OLED驱动显示图像
1. 干点啥?驱动一下上面的屏吧 2. 找个代码研究一下,cat命令用于读取文件(普通文件或设备文件)的内容并进行输出.据说板子已经做好OLED的驱动了,驱动映射为/dev/zed_oled,所以直接 ...
- idea开启jquery提示及如何找到学习目标
idea开启jquery提示 根据这些library就知道该学习哪些技术了
- shell loop
#!/bin/sh date i=0 while [ $i -le 30 ] do echi $i /usr/sbin/r2/np_test_acl -f rule.txt i=$(e ...
- 这才是球王应有的技艺,他就是C罗
四年一度的世界杯在本周四拉开了帷幕,俄罗斯以5:0碾压沙特阿拉伯,让我们惊呼战斗名族的强大,其后的摩洛哥VS伊朗,摩洛哥前锋布哈杜兹将足球顶入自家球门,这......咳,咳,本来是为了解围,没想到成就 ...
- 微软职位内部推荐-Senior Software Engineer II-Sharepoint
微软近期Open的职位: SharePoint is a multi-billion dollar enterprise business that has grown from an on-prem ...
- ES6的新特性(5)——数值的扩展
数值的扩展 二进制和八进制表示法 ES6 提供了二进制和八进制数值的新的写法,分别用前缀0b(或0B)和0o(或0O)表示. 0b111110111 === 503 // true 0o767 === ...