1. 网络编程
1.1 网络编程基本概念
1、网络
将不同区域的电脑连接到一起,组成局域网、城域网或广域网。把分布在不同地理区域的计算机与专门的外部设备用通信线路互联成一个规模大、功能强的网络系统,从而使众多的计算机可以方便地互相传递信息,共享硬件、软件、数据信息等资源。
2、计算机网络
是指将地理位置相同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统、网络管理软件及通信协议的管理和协调下,实现资源共享和信息传递的计算机系统
3、通信协议
计算机网络中实现通信必须有一些约定即通信协议,对速率、传输代码、代码结构、传输控制步骤、出错控制等制定标准
4、通信接口
为了使两个结点之间能进行对话,必须在它们之间建立通信工具(即接口),使彼此之间能进行信息交换
接口包括两部分:
硬件装置:实现节点之间的信息传送
软件装置:规定双方进行通信的约定协议
网络分层
由于结点之间联系很复杂,在指定协议时,把复杂成份分解成一些简单的成份,再将他们复合起来。最常用的复合方式是层次方式,即同层间可以通信、上一层可以调用下一层,而与再下一层不发生关系
TCP/IP是一个协议族,也是按照层次划分,共四层:应用层,传输层,互连网络层,接口层(物理+数据链路层)
OSI网络通信协议模型,是一个参考模型,而TCP/IP协议是事实上的标准。TCP/IP协议参考了OSI模型,但是并没有严格按照OSI规定的七层标准去划分,而只划分了四层,这样会更简单点,当划分太多层时,你很难区分某个协议是属于哪个层次的
这里主要关注传输层 - TCP、UDP
1.2 网络编程三要素
1、IP地址
要想让网络中的计算机能够互相通信,必须为计算机指定一个标识号,通过这个标识号来指定要接受数据的计算机和识别发送的计算机,而IP地址就是这个标识号,也就是设备的标识。
2、端口
网络的通信,本质上是两个应用程序的通信。每台计算机都有很多的应用程序,那么在网络通信时,如何区别这些应用程序呢?如果说IP地址可以唯一的标识网络中的设备,那么端口号就可以唯一标识设备中的应用程序,也就是应用程序的标识。
3、协议
通过计算机网络可以使多台计算机实现连接,位于同一网络中的计算机进行连接和通信时需要遵守一定的规则,这就好比在道路中行驶的汽车一定要遵守交通规则一样。在计算机网络中,这些连接和通信的规则被称为计算机网络通信协议。它对数据的传输格式、传输速率、传输步骤等做了统一规定,通信双方必须同时遵守才能完成数据交换。
常见的协议有TCP协议和UDP协议
1.3 IP地址
IP地址:是网络中设备的唯一标识
IP地址分为两大类
IPv4:是给每个连接在网络上的主机分配一个32bit地址。按照TCP/IP规定,IP地址用二进制来表示,每个IP地址的长32bit,也就是4个字节。例如一个采用二进制形式的地址是“11000000 10101000 00000001 01000010”,这么长的地址,处理起来也太费劲了。为了方便使用,IP地址经常被写成十进制的形式,中间使用符号“ . ”分隔不同的字节。于是,上面的IP地址可以表示为“192.168.1.66”。IP地址的这种表示法叫做 “点分十进制法”,这显然比1和0容易记得多
IPv6:由于互联网的蓬勃发展,IP地址的需求量愈来愈大,但是网络地址资源有限,使得IP的分配越发紧张。为了扩大地址空间,通过IPv6重新定义地址空间,采用128bit地址长度,每16个字节一组,分成8组十六进制数,这就解决了网络地址资源数量不够的问题。
常用DOS命令
ipconfig /all:查看本机IP地址
ping IP地址:检查网络是否连通
特殊IP地址
- 127.0.0.1:是回送地址,可以代表本机地址,一般用来测试使用
- 190.168.0.0 – 192.168.255.255:私有地址,属于非注册地址,专门为组织机构内部使用
1.4 InetAddress 的使用
为了方便我们对IP地址的获取和操作,Java提供了一个类InetAddress供我们使用
InetAddress:此类表示Internet协议(IP)地址,用于封装计算机的IP地址和DNS(没有端口信息)
方法名 | 说明 |
static InetAddress getByName(String host) | 确定主机名称的IP地址。主机名称可以是机器名称,也可以是IP地址和域名 |
String getHostName() | 获取此IP地址的主机名 |
String getHostAddress() | 返回文本显示中的IP地址字符串 |
import java.net.*;
public class InetAddressTest1
{
public static void main(String[] args) throws UnknownHostException
{
InetAddress ia = InetAddress.getByName("192.168.1.104");
System.out.println(ia);
InetAddress localhost = InetAddress.getByName("localhost");
System.out.println(localhost);
InetAddress ia2 = InetAddress.getByName("CX001");
System.out.println(ia2);
InetAddress ia3 = InetAddress.getByName("www.baidu.com");
System.out.println(ia3);
System.out.println(ia3.getHostName());
System.out.println(ia3.getHostAddress());
}
}
/**
D:\cs>javac -d . InetAddressTest1.java
D:\cs>java InetAddressTest1
/192.168.1.104
localhost/127.0.0.1
CX001/192.168.0.192
www.baidu.com/220.181.38.149
www.baidu.com
220.181.38.149
D:\cs>java InetAddressTest1
/192.168.1.104
localhost/127.0.0.1
CX001/192.168.0.192
www.baidu.com/220.181.38.149
www.baidu.com
220.181.38.149
D:\cs>javap -c InetAddressTest1
Compiled from "InetAddressTest1.java"
public class InetAddressTest1 {
public InetAddressTest1();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]) throws java.net.UnknownHostException;
Code:
0: ldc #2 // String 192.168.1.104
2: invokestatic #3 // Method java/net/InetAddress.getByName:(Ljava/lang/String;)Ljava/net/InetAddress;
5: astore_1
6: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
9: aload_1
10: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
13: ldc #6 // String localhost
15: invokestatic #3 // Method java/net/InetAddress.getByName:(Ljava/lang/String;)Ljava/net/InetAddress;
18: astore_2
19: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
22: aload_2
23: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
26: ldc #7 // String CX001
28: invokestatic #3 // Method java/net/InetAddress.getByName:(Ljava/lang/String;)Ljava/net/InetAddress;
31: astore_3
32: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
35: aload_3
36: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
39: ldc #8 // String www.baidu.com
41: invokestatic #3 // Method java/net/InetAddress.getByName:(Ljava/lang/String;)Ljava/net/InetAddress;
44: astore 4
46: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
49: aload 4
51: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
54: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
57: aload 4
59: invokevirtual #9 // Method java/net/InetAddress.getHostName:()Ljava/lang/String;
62: invokevirtual #10 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
65: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
68: aload 4
70: invokevirtual #11 // Method java/net/InetAddress.getHostAddress:()Ljava/lang/String;
73: invokevirtual #10 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
76: return
}
*/
1.5 端口
端口相关概念
端口:设备上应用程序的唯一标识
端口号: 用两个字节表示的整数,它的取值范围是0 - 65535。
公认端口:0 - 1023之间的端口号用于一些知名的网络服务和应用,比如80端口分配给www,21端口分配给FTP**
注册端口:1024 - 49151 分配给用户进程或应用程序**
动态/私有端口: 49152 - 65535
如果端口号被另外一个服务或应用所占用,会导致当前程序启动失败
端口相关DOS命令
查看所有端口:netstat -ano
查看指定端口:netstat -aon|findstr "80"
查看指定进程:tasklist|findstr "12476"
查看具体程序:使用任务管理器查看PID
IntetSocketAddress类
- 包含IP和端口信息,常用于Socket通信。此类实现IP套接字地址(IP地址+端口号),不依赖任何协议
常用构造器
构造方法 说明
InetSocketAddress(InetAddress addr, int port) 从IP地址和端口号创建套接字地址
InetSocketAddress(int port) 创建一个套接字地址,其中IP地址为通配符地址,端口号为指定值
InetSocketAddress(String hostname, int port) 根据主机名和端口号创建套接字地址
常用方法
方法 说明
InetAddress getAddress() 获得 InetAddress
int getPort() 获取端口号
String getHostName() 获取主机名
import java.net.*;
public class PostTest
{
public static void main(String[] args)
{
InetSocketAddress socketAddress = new InetSocketAddress("127.0.0.1",8080);
InetSocketAddress socketAddress2 = new InetSocketAddress("localhost",9000);
System.out.println(socketAddress.getHostName());
System.out.println(socketAddress.getAddress());
System.out.println(socketAddress.getPort());
System.out.println(socketAddress2.getHostName());
System.out.println(socketAddress2.getAddress());
System.out.println(socketAddress2.getPort());
}
}
/**
D:\cs>javac -d . PostTest.java
D:\cs>java PostTest
127.0.0.1
127.0.0.1/127.0.0.1
8080
localhost
localhost/127.0.0.1
9000
D:\cs>javap -c PostTest
Compiled from "PostTest.java"
public class PostTest {
public PostTest();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: new #2 // class java/net/InetSocketAddress
3: dup
4: ldc #3 // String 127.0.0.1
6: sipush 8080
9: invokespecial #4 // Method java/net/InetSocketAddress."<init>":(Ljava/lang/String;I)V
12: astore_1
13: new #2 // class java/net/InetSocketAddress
16: dup
17: ldc #5 // String localhost
19: sipush 9000
22: invokespecial #4 // Method java/net/InetSocketAddress."<init>":(Ljava/lang/String;I)V
25: astore_2
26: getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream;
29: aload_1
30: invokevirtual #7 // Method java/net/InetSocketAddress.getHostName:()Ljava/lang/String;
33: invokevirtual #8 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
36: getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream;
39: aload_1
40: invokevirtual #9 // Method java/net/InetSocketAddress.getAddress:()Ljava/net/InetAddress;
43: invokevirtual #10 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
46: getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream;
49: aload_1
50: invokevirtual #11 // Method java/net/InetSocketAddress.getPort:()I
53: invokevirtual #12 // Method java/io/PrintStream.println:(I)V
56: getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream;
59: aload_2
60: invokevirtual #7 // Method java/net/InetSocketAddress.getHostName:()Ljava/lang/String;
63: invokevirtual #8 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
66: getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream;
69: aload_2
70: invokevirtual #9 // Method java/net/InetSocketAddress.getAddress:()Ljava/net/InetAddress;
73: invokevirtual #10 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
76: getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream;
79: aload_2
80: invokevirtual #11 // Method java/net/InetSocketAddress.getPort:()I
83: invokevirtual #12 // Method java/io/PrintStream.println:(I)V
86: return
}
*/
关于localhost
1.6 URL
URL基本概念
URL: Uniform Resource Locator 统一资源定位符
表示统一资源定位符,指向万维网上的“资源”的指针。用于区分、定位资源
一个标准的URL必须包括:protocol(方案或协议)、host(主机)、port(端口)、path(路径)、parameter( 查询参数)、anchor(锚点)
在www上,每一信息资源都有统一且唯一的地址
如:http://www.google.com:80/index.html,分四部分组成:协议、存放资源的主机域名、端口号、资源文件名。
URL类
构造器 说明
URL(String spec) 从 String表示形成一个 URL对象
常用方法 说明
String getProtocol() 获取此 URL的协议名称
String getHost() 获取此 URL的主机名(如适用)
int getPort() 获取此 URL的端口号
String getPath() 获取此 URL的路径部分
String getFile() 获取此 URL的文件名
String getQuery() 获取参数
String getRef() 获取锚点
import java.net.*;
import java.io.*;
public class URLTest2
{
public static void main(String[] args)
{
try
{
URL url = new URL("http://www.runoob.com/index.html?language=cn#j2se");
System.out.println("URL为:" + url.toString());
System.out.println("协议为:" + url.getProtocol());
System.out.println("验证信息为:" + url.getAuthority());
System.out.println("文件名及请求参数:" + url.getFile());
System.out.println("主机名:" + url.getHost());
System.out.println("路径:" + url.getPath());
System.out.println("端口:" + url.getPort());
System.out.println("默认端口:" + url.getDefaultPort());
System.out.println("请求参数:" + url.getQuery());
System.out.println("定位位置:" + url.getRef());
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
/**
D:\cs>javac -d . URLTest2.java
D:\cs>java URLTest2
URL为:http://www.runoob.com/index.html?language=cn#j2se
协议为:http
验证信息为:www.runoob.com
文件名及请求参数:/index.html?language=cn
主机名:www.runoob.com
路径:/index.html
端口:-1
默认端口:80
请求参数:language=cn
定位位置:j2se
D:\cs>javap -c URLTest2
Compiled from "URLTest2.java"
public class URLTest2 {
public URLTest2();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: new #2 // class java/net/URL
3: dup
4: ldc #3 // String http://www.runoob.com/index.html?language=cn#j2se
6: invokespecial #4 // Method java/net/URL."<init>":(Ljava/lang/String;)V
9: astore_1
10: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
13: aload_1
14: invokevirtual #6 // Method java/net/URL.toString:()Ljava/lang/String;
17: invokedynamic #7, 0 // InvokeDynamic #0:makeConcatWithConstants:(Ljava/lang/String;)Ljava/lang/String;
22: invokevirtual #8 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
25: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
28: aload_1
29: invokevirtual #9 // Method java/net/URL.getProtocol:()Ljava/lang/String;
32: invokedynamic #10, 0 // InvokeDynamic #1:makeConcatWithConstants:(Ljava/lang/String;)Ljava/lang/String;
37: invokevirtual #8 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
40: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
43: aload_1
44: invokevirtual #11 // Method java/net/URL.getAuthority:()Ljava/lang/String;
47: invokedynamic #12, 0 // InvokeDynamic #2:makeConcatWithConstants:(Ljava/lang/String;)Ljava/lang/String;
52: invokevirtual #8 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
55: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
58: aload_1
59: invokevirtual #13 // Method java/net/URL.getFile:()Ljava/lang/String;
62: invokedynamic #14, 0 // InvokeDynamic #3:makeConcatWithConstants:(Ljava/lang/String;)Ljava/lang/String;
67: invokevirtual #8 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
70: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
73: aload_1
74: invokevirtual #15 // Method java/net/URL.getHost:()Ljava/lang/String;
77: invokedynamic #16, 0 // InvokeDynamic #4:makeConcatWithConstants:(Ljava/lang/String;)Ljava/lang/String;
82: invokevirtual #8 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
85: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
88: aload_1
89: invokevirtual #17 // Method java/net/URL.getPath:()Ljava/lang/String;
92: invokedynamic #18, 0 // InvokeDynamic #5:makeConcatWithConstants:(Ljava/lang/String;)Ljava/lang/String;
97: invokevirtual #8 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
100: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
103: aload_1
104: invokevirtual #19 // Method java/net/URL.getPort:()I
107: invokedynamic #20, 0 // InvokeDynamic #6:makeConcatWithConstants:(I)Ljava/lang/String;
112: invokevirtual #8 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
115: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
118: aload_1
119: invokevirtual #21 // Method java/net/URL.getDefaultPort:()I
122: invokedynamic #22, 0 // InvokeDynamic #7:makeConcatWithConstants:(I)Ljava/lang/String;
127: invokevirtual #8 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
130: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
133: aload_1
134: invokevirtual #23 // Method java/net/URL.getQuery:()Ljava/lang/String;
137: invokedynamic #24, 0 // InvokeDynamic #8:makeConcatWithConstants:(Ljava/lang/String;)Ljava/lang/String;
142: invokevirtual #8 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
145: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
148: aload_1
149: invokevirtual #25 // Method java/net/URL.getRef:()Ljava/lang/String;
152: invokedynamic #26, 0 // InvokeDynamic #9:makeConcatWithConstants:(Ljava/lang/String;)Ljava/lang/String;
157: invokevirtual #8 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
160: goto 168
163: astore_1
164: aload_1
165: invokevirtual #28 // Method java/io/IOException.printStackTrace:()V
168: return
Exception table:
from to target type
0 160 163 Class java/io/IOException
}
*/
1.7 协议
协议:计算机网络中,连接和通信的规则被称为网络通信协议
1、UDP协议
用户数据报协议(User Datagram Protocol)
UDP是无连接通信协议,即在数据传输时,数据的发送端和接收端不建立逻辑连接。简单来说,当一台计算机向另外一台计算机发送数据时,发送端不会确认接收端是否存在,就会发出数据,同样接收端在收到数据时,也不会向发送端反馈是否收到数据
由于使用UDP协议消耗资源少,通信效率高,所以通常都会用于音频、视频和普通数据的传输
例如视频会议通常采用UDP协议,因为这种情况即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。但是在使用UDP协议传送数据时,由于UDP的面向无连接性,不能保证数据的完整性,因此在传输重要数据时不建议使用UDP协议
2、TCP协议
传输控制协议(Transmission Control Protocol)
TCP协议是面向连接的通信协议,即传输数据之前,在发送端和接收端建立逻辑连接,然后再传输数据,它提供了两台计算机之间可靠无差错的数据出啊u念书。在TCP连接中必须明确客户端与服务器端,由于客户端向服务器端发出连接请求,每次连接的创建都需要经过“三次握手”
三次握手
TCP协议中,在发送数据的准备阶段,客户端与服务器之间的三次交互,以保证连接的可靠
第一次握手:客户端向服务器端发出连接请求,等待服务器确认
第二次握手:服务器端向客户端回送一个响应,通知客户端收到了连接请求
第三次握手:客户端再次向服务器端发送确认信息,确认连接
完成三次握手,连接建立后,客户端和服务器就可以开始进行数据传输了。由于这种面向连接的特性,TCP协议可以保证传输数据的安全,所以应用非常广泛。例如上传文件、下载文件、浏览网页
2. UDP通信程序
2.1 UDP通信原理
UDP协议是一种不可靠的网络协议,它在通信的两端各建立一个Socket对象,但是这两个Socket只是发送,接收数据的对象
基于UDP协议的通信双方而言,没有客户端和服务器概念
Java提供了DatagramSocket类和DatagramPacket类
DatagramSocket:用于发送或接收数据包的套接字
DatagramPacket:数据包
DatagramSocket类
此类表示用于发送和接收数据报数据包的套接字
数据报套接字是分组传送服务的发送或接收点
常用构造器
常用构造器 说明
DatagramSocket() 构造数据报套接字并将其绑定到本地主机上的任何可用端口
DatagramSocket(int port) 构造数据报套接字并将其绑定到本地主机上的指定端口
常用方法
常用方法 说明
void send(DatagramPacket p) 从此套接字发送数据报包
void receive(DatagramPacket p) 从此套接字接收数据报包(阻塞式的接收)
DatagramPacket类
该类表示数据报包
数据报包用于实现无连接分组传送服务
常用构造器
常用构造器 说明
(接收方) DatagramPacket(byte[] buf, int length) 构造一个 DatagramPacket用于接收长度的数据包 length
(发送方)DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port) 构造用于发送指定长度的数据报包到指定主机的指定端口号上
常用方法
常用方法 说明
int getLength() 返回要发送的数据的长度或接收到的数据的长度
byte[] getData() 返回数据缓冲区
三个概念:数据包(Packet)、数据报(Datagram)和套接字(Socket)
1、数据报(Datagram)
数据报是通过网络传输的数据的基本单元,包含一个报头(header)和数据本身,其中报头描述了数据的目的地以及和其它数据之间的关系。数据报是完备的、独立的数据实体,该实体携带要从源计算机传递到目的计算机的信息,该信息不依赖以前在源计算机和目的计算机以及传输网络间交换。
UDP数据报的长度是指包括报头和数据部分在内的总字节数,其中报头长度固定,数据部分可变。数据报的最大长度根据操作环境的不同而各异。从理论上说,包含报头在内的数据报的最大长度为65535字节(64K)
我们在用Socket编程时,UDP协议要求包小于64K,TCP没有限定
2、套接字(Socket)
所谓套接字(Socket),就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象
从所处的地位来讲,套接字上联应用进程,下联网络协议栈,是应用程序通过网络协议进行通信的接口,是应用程序与网络协议根进行交互的接口
3、数据包(Packet)
包(Packet)是TCP/IP协议通信传输中的数据单位,一般也称“数据包”
2.2 UDP发送数据
发送数据的步骤
1、创建发送端的Socket对象(DatagramSocket)。如果没有指定端口,发送到本地主机所有可用端口(不常用),这里可以采用指定端口构造方法
DatagramSocket(),DatagramSocket(int port)|
2、创建数据,并把数据封装成DatagramPacket包裹,数据一定要转成字节数组,同时需要指定IP地址和端口
DatagramPacket(byte[] buf, int length, InetAddress address, int port)
3、调用DatagraSocket对象的方法发送数据包裹
void send(DatagramPacket p)
4、关闭发送端,释放资源
void close()
import java.net.*;
import java.io.*;
public class SendDemo
{
public static void main(String[] args) throws IOException
{
DatagramSocket ds = new DatagramSocket();
byte[] bys = "Java YYDS!".getBytes();
DatagramPacket dp = new DatagramPacket(bys,bys.length,InetAddress.getByName("127.0.0.1"),10086);
ds.send(dp);
ds.close();
}
}
/**
D:\cs>javac -d . SendDemo.java
D:\cs>java SendDemo
D:\cs>javap -c SendDmeo
错误: 找不到类: SendDmeo
D:\cs>javac -d . SendDemo.java
D:\cs>java SendDemo
D:\cs>javap -c SendDemo
Compiled from "SendDemo.java"
public class SendDemo {
public SendDemo();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]) throws java.io.IOException;
Code:
0: new #2 // class java/net/DatagramSocket
3: dup
4: invokespecial #3 // Method java/net/DatagramSocket."<init>":()V
7: astore_1
8: ldc #4 // String Java YYDS!
10: invokevirtual #5 // Method java/lang/String.getBytes:()[B
13: astore_2
14: new #6 // class java/net/DatagramPacket
17: dup
18: aload_2
19: aload_2
20: arraylength
21: ldc #7 // String 127.0.0.1
23: invokestatic #8 // Method java/net/InetAddress.getByName:(Ljava/lang/String;)Ljava/net/InetAddress;
26: sipush 10086
29: invokespecial #9 // Method java/net/DatagramPacket."<init>":([BILjava/net/InetAddress;I)V
32: astore_3
33: aload_1
34: aload_3
35: invokevirtual #10 // Method java/net/DatagramSocket.send:(Ljava/net/DatagramPacket;)V
38: aload_1
39: invokevirtual #11 // Method java/net/DatagramSocket.close:()V
42: return
}
*/
import java.net.*;
import java.io.*;
public class UDPClient
{
public static void main(String[] args) throws Exception
{
System.out.println("发送方启动中...");
DatagramSocket client = new DatagramSocket(8888);
String data = "Java YYDS";
byte[] datas = data.getBytes();
DatagramPacket packet = new DatagramPacket(datas,0,datas.length,new InetSocketAddress("localhost",9999));
client.send(packet);
client.close();
}
}
/**
D:\cs>javac -d . UDPClient.java
D:\cs>java UDPClient
发送方启动中...
D:\cs>javap -c UDPClient
Compiled from "UDPClient.java"
public class UDPClient {
public UDPClient();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]) throws java.lang.Exception;
Code:
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String 发送方启动中...
5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: new #5 // class java/net/DatagramSocket
11: dup
12: sipush 8888
15: invokespecial #6 // Method java/net/DatagramSocket."<init>":(I)V
18: astore_1
19: ldc #7 // String Java YYDS
21: astore_2
22: aload_2
23: invokevirtual #8 // Method java/lang/String.getBytes:()[B
26: astore_3
27: new #9 // class java/net/DatagramPacket
30: dup
31: aload_3
32: iconst_0
33: aload_3
34: arraylength
35: new #10 // class java/net/InetSocketAddress
38: dup
39: ldc #11 // String localhost
41: sipush 9999
44: invokespecial #12 // Method java/net/InetSocketAddress."<init>":(Ljava/lang/String;I)V
47: invokespecial #13 // Method java/net/DatagramPacket."<init>":([BIILjava/net/SocketAddress;)V
50: astore 4
52: aload_1
53: aload 4
55: invokevirtual #14 // Method java/net/DatagramSocket.send:(Ljava/net/DatagramPacket;)V
58: aload_1
59: invokevirtual #15 // Method java/net/DatagramSocket.close:()V
62: return
}
*/
2.3 UDP接收数据
接收数据的步骤
1、创建接收端的Socket对象(DatagramSocket),指定端口
DatagramSocket(int port)
2、准备容器,封装成DatagramPacket包裹,用于接收数据
DatagramPacket(byte[] buf, int length)
3、调用DatagramSocket对象的方法,阻塞式接收包裹
void receive(DatagramPacket p)
4、解析数据包,并把数据在控制台显示
byte[] getData() 和 int getLength()
5、关闭接收端,释放资源
void close()
import java.net.*;
import java.io.*;
public class ReceiveDemo
{
public static void main(String[] args) throws IOException
{
DatagramSocket ds = new DatagramSocket(10086);
byte[] bys = new byte[1024];
DatagramPacket dp = new DatagramPacket(bys,bys.length);
ds.receive(dp);
System.out.println("数据是:" + new String(dp.getData(),0,dp.getLength()));
ds.close();
}
}
/**
D:\cs>javac -d . ReceiveDemo.java
D:\cs>java ReceiveDemo
数据是:Java YYDS!
D:\cs>javap -c ReceiveDemo
Compiled from "ReceiveDemo.java"
public class ReceiveDemo {
public ReceiveDemo();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]) throws java.io.IOException;
Code:
0: new #2 // class java/net/DatagramSocket
3: dup
4: sipush 10086
7: invokespecial #3 // Method java/net/DatagramSocket."<init>":(I)V
10: astore_1
11: sipush 1024
14: newarray byte
16: astore_2
17: new #4 // class java/net/DatagramPacket
20: dup
21: aload_2
22: aload_2
23: arraylength
24: invokespecial #5 // Method java/net/DatagramPacket."<init>":([BI)V
27: astore_3
28: aload_1
29: aload_3
30: invokevirtual #6 // Method java/net/DatagramSocket.receive:(Ljava/net/DatagramPacket;)V
33: getstatic #7 // Field java/lang/System.out:Ljava/io/PrintStream;
36: new #8 // class java/lang/String
39: dup
40: aload_3
41: invokevirtual #9 // Method java/net/DatagramPacket.getData:()[B
44: iconst_0
45: aload_3
46: invokevirtual #10 // Method java/net/DatagramPacket.getLength:()I
49: invokespecial #11 // Method java/lang/String."<init>":([BII)V
52: invokedynamic #12, 0 // InvokeDynamic #0:makeConcatWithConstants:(Ljava/lang/String;)Ljava/lang/String;
57: invokevirtual #13 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
60: aload_1
61: invokevirtual #14 // Method java/net/DatagramSocket.close:()V
64: return
}
*/
import java.net.*;
import java.io.*;
public class UDPServer
{
public static void main(String[] args) throws Exception
{
System.out.println("接受方启动中...");
DatagramSocket server = new DatagramSocket(9999);
byte[] container = new byte[1024 * 60];
DatagramPacket packet = new DatagramPacket(container,0,container.length);
server.receive(packet);
byte[] datas = packet.getData();
int len = packet.getLength();
System.out.println(new String(datas,0,len));
server.close();
}
}
/**
D:\cs>javac -d . UDPServer.java
D:\cs>java UDPServer
接受方启动中...
Java YYDS
D:\cs>javap -c UDPServer
Compiled from "UDPServer.java"
public class UDPServer {
public UDPServer();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]) throws java.lang.Exception;
Code:
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String 接受方启动中...
5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: new #5 // class java/net/DatagramSocket
11: dup
12: sipush 9999
15: invokespecial #6 // Method java/net/DatagramSocket."<init>":(I)V
18: astore_1
19: ldc #7 // int 61440
21: newarray byte
23: astore_2
24: new #8 // class java/net/DatagramPacket
27: dup
28: aload_2
29: iconst_0
30: aload_2
31: arraylength
32: invokespecial #9 // Method java/net/DatagramPacket."<init>":([BII)V
35: astore_3
36: aload_1
37: aload_3
38: invokevirtual #10 // Method java/net/DatagramSocket.receive:(Ljava/net/DatagramPacket;)V
41: aload_3
42: invokevirtual #11 // Method java/net/DatagramPacket.getData:()[B
45: astore 4
47: aload_3
48: invokevirtual #12 // Method java/net/DatagramPacket.getLength:()I
51: istore 5
53: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
56: new #13 // class java/lang/String
59: dup
60: aload 4
62: iconst_0
63: iload 5
65: invokespecial #14 // Method java/lang/String."<init>":([BII)V
68: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
71: aload_1
72: invokevirtual #15 // Method java/net/DatagramSocket.close:()V
75: return
}
*/
注意
1、同一台机器操作时,如果发送包裹的目的地端口和接收端的端口名不一致时,将会导致包裹丢失,接收不到数据
2、如果同一台机器下采用重复端口,会报错BindException: Address already in use: bind
端口重复使用
2.4 UDP程序练习
练习一:简单的信息发送
- 发送端:数据来自键盘录入,知道输入的数据是886,发送数据结束
- 接收端:因为接收端不知道发送端什么时候停止发送,故采用死循环接收
- 发送端
/** * UDP发送数据: * 数据来自键盘录入,知道输入的数据是886,发送数据结束 */ import java.io.*; import java.net.*; public class SendDemo { public static void main(String[] args) throws IOException { // 创建接收端的Socket对象(DatagramSocket) DatagramSocket ds = new DatagramSocket(); // 自己封装键盘录入数据 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String line; while ((line=br.readLine()) != null) { if ("886".equals(line)) { break; } // 创建数据,把数据打包 byte[] bys = line.getBytes(); DatagramPacket dp = new DatagramPacket(bys, bys.length, InetAddress.getByName("127.0.0.1"), 12345); // 调用DatagramSocket对象的方法来发送数据 ds.send(dp); } // 关闭发送端 ds.close(); } }
接收端
/** * UDP接收数据: * 因为接收端不知道发送端什么时候停止发送,故采用死循环接收 */ import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; public class ReceiveDemo { public static void main(String[] args) throws IOException { // 1、创建接收端的Socket对象(DatagramSocket) DatagramSocket ds = new DatagramSocket(12345); while (true) { // 2、创建一个数据包,用于接收数据 byte[] bys = new byte[1024]; DatagramPacket dp = new DatagramPacket(bys, bys.length); // 3、调用DatagramSocket对象的方法接收数据 ds.receive(dp); // 4、解析数据包,并把数据在控制台显示 // int getLength(): 返回要发送的数据的长度或接收到的数据的长度。 System.out.println("接收到的数据是:" + new String(dp.getData(), 0, dp.getLength())); } // 5、关闭接收端 // ds.close(); } }
练习二:一对一线上咨询
需求:
- 完成在线咨询功能
- 学生和咨询师在线一对一交流
- 加入多线程,可以双向交流
- 聊天终止条件为输入"bye"
- 发送端:
/** * 发送端:使用面向对象封装 */ import java.io.*; import java.net.*; public class TalkSend implements Runnable { private DatagramSocket client; private BufferedReader reader; private String toIP; // 对方的IP地址 private int toPort; // 对方的端口 public TalkSend(int port, String toIP, int toPort) { this.toIP = toIP; this.toPort = toPort; try { client = new DatagramSocket(port); reader = new BufferedReader(new InputStreamReader(System.in)); } catch (SocketException e) { e.printStackTrace(); } } @Override public void run() { while (true) { String data; try { data = reader.readLine(); byte[] datas = data.getBytes(); // 封装成DatagramPacket包裹,指定目的地 DatagramPacket packet = new DatagramPacket(datas, 0, datas.length, new InetSocketAddress(this.toIP, this.toPort)); client.send(packet); // 终止条件 if (data.equals("bye")) { break; } } catch (IOException e) { e.printStackTrace(); } } // 释放资源 client.close(); } }
接受端:
/** * 接收端:使用面向对象封装 */ import java.net.*; import java.io.*; public class TalkReceive implements Runnable { private DatagramSocket server; private String from; public TalkReceive(int port, String from) { this.from = from; try { server = new DatagramSocket(port); } catch (SocketException e) { e.printStackTrace(); } } @Override public void run() { while (true) { // 准备容器,封装成DatagramPacket包裹 byte[] container = new byte[1024 * 60]; DatagramPacket packet = new DatagramPacket(container, 0, container.length); try { // 阻塞式接收包裹 server.receive(packet); // 分析数据 byte[] datas = packet.getData(); int len = packet.getLength(); String data = new String(datas, 0, len); System.out.println(from + " : " + data); if (data.equals("bye")) { break; } } catch (IOException e) { e.printStackTrace(); } } // 释放资源 server.close(); } }
学生方
/** * 加入多线程,实现双向交流,模拟在线咨询 */ public class TalkStudent { public static void main(String[] args) { new Thread(new TalkSend(7777, "localhost", 9999)).start(); // 发送 new Thread(new TalkReceive(8888, "老师")).start(); //接收 } }
老师方
/** * 加入多线程,实现双向交流,模拟在线咨询 */ public class TalkTeacher { public static void main(String[] args) { new Thread(new TalkReceive(9999, "学生")).start(); //接收 new Thread(new TalkSend(5555, "localhost", 8888)).start(); // 发送 } }
- 学生和老师端同时输入"bye",程序才会同时结束,只是一端输入"bye",会进行等待操作
-
3. TCP通信程序
3.1 TCP通信原理
TCP通信协议是一种可靠的网络协议,它在通信的两端各建立一个Socket对象,从而在通信的两端形成网络虚拟链路,一旦建立了虚拟的网络链路,两端的程序就可以通过虚拟链路进行通信。使用基于TCP协议的Socket网络编程实现,使用Socket对象来代表两端的通信端口
TCP协议基于请求-响应模式,第一次主动发起的程序被称为客户端(Client)程序
第一次通讯中等待连接的程序被称为服务器端(Sercer)程序
利用IO流实现数据的传输
-
-
原理说明及详细步骤
-
1、在服务端指定一个端口号来创建ServerSocket,并使用accept方法进行侦听,这将阻塞服务器线程,等待用户请求。
2、在客户端指定服务的主机IP和端口号来创建socket,并连接服务端ServerSocket,此时服务端accept方法被唤醒,同时返回一个和客户端通信的socket。
3、在客户端和服务端分别使用socket来获取网络通信输入/输出流,并按照一定的通信协议对socket进行读/写操作。
4、通信完成后,在客户端和服务端中分别关闭socket。
1、服务器端
创建ServerSocket(int port)对象
在Socket上使用accept方法监听客户端的连接请求
阻塞、等待连接的建立
接收并处理请求信息
将处理结果返回给客户端
关闭流和Socket对象
2、客户端
创建Socket(String host, int port)对象
向服务器发送连接请求
向服务器发送服务请求
接受服务结果(服务响应)
关闭流和Socket对象
Java为客户端提供了Socket类,为服务器端提供了ServerSocket类
Socket类
常用构造器
构造方法 说明
Socket(InetAddress address, int port) 创建流套接字并将其连接到指定IP地址的指定端口号
Socket(String host, int port) 创建流套接字并将其连接到指定主机上的指定端口号
常用方法
常用方法 说明
OutputStream getOutputStream() 返回此套接字的输出流
InputStream getInputStream() 返回此套接字的输入流
void shutdownOutput() 禁用此套接字的输出流
ServerSocket类
常用构造器
构造方法 | 说明 |
---|---|
ServerSocket(int port) | 创建绑定到指定端口的服务器套接字 |
常用方法
常用方法 | 说明 |
---|---|
Socket accept() | 侦听要连接到此套接字并接受它 |
3.2 TCP发送数据
发送数据的步骤
1、创建客户端的Socket对象(Socket)Socket(String host, int port)
2、获取输出流,写数据OutputStream getOutputStream()
3、释放资源
import java.io.*;
import java.net.*;
public class ClientDemo2
{
public static void main(String[] args) throws IOException
{
// 创建客户端的Socket对象(Socket)
// Socket(InetAddress address, int port): 创建流套接字并将其连接到指定IP地址的指定端口号
// Socket s = new Socket(InetAddress.getByName("127.0.0.1"), 10005);
// Socket(String host, int port): 创建流套接字并将其连接到指定主机上的指定端口号。
Socket s = new Socket("127.0.0.1",10005);
// 获取输出流,写数据
// OutputStream getOutputStream(): 返回此套接字的输出流。
OutputStream os = s.getOutputStream();
os.write("Java YYDS!".getBytes());
//释放资源
s.close();
os.close();
}
}
/**
D:\cs>javac -d . ClientDemo2.java
D:\cs>java ClientDemo2
D:\cs>javap -c ClientDemo2
Compiled from "ClientDemo2.java"
public class ClientDemo2 {
public ClientDemo2();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]) throws java.io.IOException;
Code:
0: new #2 // class java/net/Socket
3: dup
4: ldc #3 // String 127.0.0.1
6: sipush 10005
9: invokespecial #4 // Method java/net/Socket."<init>":(Ljava/lang/String;I)V
12: astore_1
13: aload_1
14: invokevirtual #5 // Method java/net/Socket.getOutputStream:()Ljava/io/OutputStream;
17: astore_2
18: aload_2
19: ldc #6 // String Java YYDS!
21: invokevirtual #7 // Method java/lang/String.getBytes:()[B
24: invokevirtual #8 // Method java/io/OutputStream.write:([B)V
27: aload_1
28: invokevirtual #9 // Method java/net/Socket.close:()V
31: return
}
*/
3.3 TCP接收数据
接收数据的步骤
1、创建服务器端的Socket对象(ServerSocket)ServerSocket(int port)
2、获取输入流,读数据,并把数据显示在控制台Socket accept()
3、释放资源
import java.io.*;
import java.net.*;
public class ServerDemo2
{
public static void main(String[] args) throws IOException
{
// 创建服务器端的Socket对象(ServerSocket)
ServerSocket ss = new ServerSocket(10005);
// Socket accept(): 侦听要连接到此套接字并接受它
Socket s = ss.accept();
// 获取输入流,读数据,并把数据显示在控制台
InputStream is = s.getInputStream();
byte[] bys = new byte[1024];
int len = is.read(bys);
String data = new String(bys,0,len);
System.out.println("数据是:" + data);
// 释放资源
ss.close();
}
}
/**
D:\cs>javac -d . ServerDemo2.java
D:\cs>java ServerDemo2
数据是:Java YYDS!
D:\cs>javap -c ServerDemo2
Compiled from "ServerDemo2.java"
public class ServerDemo2 {
public ServerDemo2();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]) throws java.io.IOException;
Code:
0: new #2 // class java/net/ServerSocket
3: dup
4: sipush 10005
7: invokespecial #3 // Method java/net/ServerSocket."<init>":(I)V
10: astore_1
11: aload_1
12: invokevirtual #4 // Method java/net/ServerSocket.accept:()Ljava/net/Socket;
15: astore_2
16: aload_2
17: invokevirtual #5 // Method java/net/Socket.getInputStream:()Ljava/io/InputStream;
20: astore_3
21: sipush 1024
24: newarray byte
26: astore 4
28: aload_3
29: aload 4
31: invokevirtual #6 // Method java/io/InputStream.read:([B)I
34: istore 5
36: new #7 // class java/lang/String
39: dup
40: aload 4
42: iconst_0
43: iload 5
45: invokespecial #8 // Method java/lang/String."<init>":([BII)V
48: astore 6
50: getstatic #9 // Field java/lang/System.out:Ljava/io/PrintStream;
53: aload 6
55: invokedynamic #10, 0 // InvokeDynamic #0:makeConcatWithConstants:(Ljava/lang/String;)Ljava/lang/String;
60: invokevirtual #11 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
63: aload_1
64: invokevirtual #12 // Method java/net/ServerSocket.close:()V
67: return
}
*/
3.4 TCP通信程序练习
先运行服务器端,再运行客户端
练习一:简单的发送和接收数据
- 客户端: 发送数据,接收服务器反馈
- 服务器: 接收数据,给出反馈
-
import java.io.*; import java.net.*; public class ClientDem3 { public static void main(String[] args) throws IOException { // 创建客户端的Socket对象(Socket) Socket s = new Socket("127.0.0.1",10005); // 获取输出流,写数据 OutputStream os = s.getOutputStream(); os.write("Java YYDS!".getBytes()); // 接收服务器反馈 InputStream is = s.getInputStream(); byte[] bys = new byte[1024]; int len = is.read(bys); String data = new String(bys,0,len); System.out.println("客户端:" + data); s.close(); } } /** D:\cs>javac -d . ClientDem3.java D:\cs>java ClientDem3 客户端:数据已经收到 D:\cs>javap -c ClientDem3 Compiled from "ClientDem3.java" public class ClientDem3 { public ClientDem3(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]) throws java.io.IOException; Code: 0: new #2 // class java/net/Socket 3: dup 4: ldc #3 // String 127.0.0.1 6: sipush 10005 9: invokespecial #4 // Method java/net/Socket."<init>":(Ljava/lang/String;I)V 12: astore_1 13: aload_1 14: invokevirtual #5 // Method java/net/Socket.getOutputStream:()Ljava/io/OutputStream; 17: astore_2 18: aload_2 19: ldc #6 // String Java YYDS! 21: invokevirtual #7 // Method java/lang/String.getBytes:()[B 24: invokevirtual #8 // Method java/io/OutputStream.write:([B)V 27: aload_1 28: invokevirtual #9 // Method java/net/Socket.getInputStream:()Ljava/io/InputStream; 31: astore_3 32: sipush 1024 35: newarray byte 37: astore 4 39: aload_3 40: aload 4 42: invokevirtual #10 // Method java/io/InputStream.read:([B)I 45: istore 5 47: new #11 // class java/lang/String 50: dup 51: aload 4 53: iconst_0 54: iload 5 56: invokespecial #12 // Method java/lang/String."<init>":([BII)V 59: astore 6 61: getstatic #13 // Field java/lang/System.out:Ljava/io/PrintStream; 64: aload 6 66: invokedynamic #14, 0 // InvokeDynamic #0:makeConcatWithConstants:(Ljava/lang/String;)Ljava/lang/String; 71: invokevirtual #15 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 74: aload_1 75: invokevirtual #16 // Method java/net/Socket.close:()V 78: return } */
import java.io.*; import java.net.*; public class ServerDem3 { public static void main(String[] args) throws IOException { // 创建服务器端的Socket对象(ServerSocket) ServerSocket ss = new ServerSocket(10005); // Socket accept(): 侦听要连接到此套接字并接受它 Socket s = ss.accept(); // 获取输入流,读数据,并把数据显示在控制台 InputStream is = s.getInputStream(); byte[] bys = new byte[1024]; int len = is.read(bys); String data = new String(bys,0,len); System.out.println("服务器:" + data); // 给出反馈 OutputStream os = s.getOutputStream(); os.write("数据已经收到".getBytes()); ss.close(); } } /** D:\cs>javac -d . ServerDem3.java D:\cs>java ServerDem3 服务器:Java YYDS! D:\cs>javap -c ServerDem3 Compiled from "ServerDem3.java" public class ServerDem3 { public ServerDem3(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]) throws java.io.IOException; Code: 0: new #2 // class java/net/ServerSocket 3: dup 4: sipush 10005 7: invokespecial #3 // Method java/net/ServerSocket."<init>":(I)V 10: astore_1 11: aload_1 12: invokevirtual #4 // Method java/net/ServerSocket.accept:()Ljava/net/Socket; 15: astore_2 16: aload_2 17: invokevirtual #5 // Method java/net/Socket.getInputStream:()Ljava/io/InputStream; 20: astore_3 21: sipush 1024 24: newarray byte 26: astore 4 28: aload_3 29: aload 4 31: invokevirtual #6 // Method java/io/InputStream.read:([B)I 34: istore 5 36: new #7 // class java/lang/String 39: dup 40: aload 4 42: iconst_0 43: iload 5 45: invokespecial #8 // Method java/lang/String."<init>":([BII)V 48: astore 6 50: getstatic #9 // Field java/lang/System.out:Ljava/io/PrintStream; 53: aload 6 55: invokedynamic #10, 0 // InvokeDynamic #0:makeConcatWithConstants:(Ljava/lang/String;)Ljava/lang/String; 60: invokevirtual #11 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 63: aload_2 64: invokevirtual #12 // Method java/net/Socket.getOutputStream:()Ljava/io/OutputStream; 67: astore 7 69: aload 7 71: ldc #13 // String 数据已经收到 73: invokevirtual #14 // Method java/lang/String.getBytes:()[B 76: invokevirtual #15 // Method java/io/OutputStream.write:([B)V 79: aload_1 80: invokevirtual #16 // Method java/net/ServerSocket.close:()V 83: return } */
-
练习二:数据来自键盘输入,接收到的数据写入文本
- 客户端: 数据来自于键盘录入,知道输入的数据是886, 发送数据结束
- 服务器端: 接收到的数据写入文本文件
-
import java.io.*; import java.net.*; public class ClientDemo4 { public static void main(String[] args) throws IOException { Socket s = new Socket("127.0.0.1",10005); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); // 封装输出流对象: 将字节输出流转为字符流 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); String line; while((line = br.readLine()) != null) { if("886".equals(line)) { break; } bw.write(line); bw.newLine(); bw.flush(); } s.close(); } } /** D:\cs>java ClientDemo4 我们在这里学Java 你好 886 D:\cs>javap -c ClientDemo4 Compiled from "ClientDemo4.java" public class ClientDemo4 { public ClientDemo4(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]) throws java.io.IOException; Code: 0: new #2 // class java/net/Socket 3: dup 4: ldc #3 // String 127.0.0.1 6: sipush 10005 9: invokespecial #4 // Method java/net/Socket."<init>":(Ljava/lang/String;I)V 12: astore_1 13: new #5 // class java/io/BufferedReader 16: dup 17: new #6 // class java/io/InputStreamReader 20: dup 21: getstatic #7 // Field java/lang/System.in:Ljava/io/InputStream; 24: invokespecial #8 // Method java/io/InputStreamReader."<init>":(Ljava/io/InputStream;)V 27: invokespecial #9 // Method java/io/BufferedReader."<init>":(Ljava/io/Reader;)V 30: astore_2 31: new #10 // class java/io/BufferedWriter 34: dup 35: new #11 // class java/io/OutputStreamWriter 38: dup 39: aload_1 40: invokevirtual #12 // Method java/net/Socket.getOutputStream:()Ljava/io/OutputStream; 43: invokespecial #13 // Method java/io/OutputStreamWriter."<init>":(Ljava/io/OutputStream;)V 46: invokespecial #14 // Method java/io/BufferedWriter."<init>":(Ljava/io/Writer;)V 49: astore_3 50: aload_2 51: invokevirtual #15 // Method java/io/BufferedReader.readLine:()Ljava/lang/String; 54: dup 55: astore 4 57: ifnull 90 60: ldc #16 // String 886 62: aload 4 64: invokevirtual #17 // Method java/lang/String.equals:(Ljava/lang/Object;)Z 67: ifeq 73 70: goto 90 73: aload_3 74: aload 4 76: invokevirtual #18 // Method java/io/BufferedWriter.write:(Ljava/lang/String;)V 79: aload_3 80: invokevirtual #19 // Method java/io/BufferedWriter.newLine:()V 83: aload_3 84: invokevirtual #20 // Method java/io/BufferedWriter.flush:()V 87: goto 50 90: aload_1 91: invokevirtual #21 // Method java/net/Socket.close:()V 94: return } */
import java.io.*; import java.net.*; public class ServerDemo4 { public static void main(String[] args) throws IOException { ServerSocket ss = new ServerSocket(10005); Socket s = ss.accept(); BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream())); BufferedWriter bw = new BufferedWriter(new FileWriter("s.txt")); String line; while((line = br.readLine()) != null) { bw.write(line); bw.newLine(); bw.flush(); } bw.close(); ss.close(); } } /** D:\cs>javac -d . ServerDemo4.java D:\cs>java ServerDemo4 D:\cs>javap -c ServerDemo4 Compiled from "ServerDemo4.java" public class ServerDemo4 { public ServerDemo4(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]) throws java.io.IOException; Code: 0: new #2 // class java/net/ServerSocket 3: dup 4: sipush 10005 7: invokespecial #3 // Method java/net/ServerSocket."<init>":(I)V 10: astore_1 11: aload_1 12: invokevirtual #4 // Method java/net/ServerSocket.accept:()Ljava/net/Socket; 15: astore_2 16: new #5 // class java/io/BufferedReader 19: dup 20: new #6 // class java/io/InputStreamReader 23: dup 24: aload_2 25: invokevirtual #7 // Method java/net/Socket.getInputStream:()Ljava/io/InputStream; 28: invokespecial #8 // Method java/io/InputStreamReader."<init>":(Ljava/io/InputStream;)V 31: invokespecial #9 // Method java/io/BufferedReader."<init>":(Ljava/io/Reader;)V 34: astore_3 35: new #10 // class java/io/BufferedWriter 38: dup 39: new #11 // class java/io/FileWriter 42: dup 43: ldc #12 // String s.txt 45: invokespecial #13 // Method java/io/FileWriter."<init>":(Ljava/lang/String;)V 48: invokespecial #14 // Method java/io/BufferedWriter."<init>":(Ljava/io/Writer;)V 51: astore 4 53: aload_3 54: invokevirtual #15 // Method java/io/BufferedReader.readLine:()Ljava/lang/String; 57: dup 58: astore 5 60: ifnull 83 63: aload 4 65: aload 5 67: invokevirtual #16 // Method java/io/BufferedWriter.write:(Ljava/lang/String;)V 70: aload 4 72: invokevirtual #17 // Method java/io/BufferedWriter.newLine:()V 75: aload 4 77: invokevirtual #18 // Method java/io/BufferedWriter.flush:()V 80: goto 53 83: aload 4 85: invokevirtual #19 // Method java/io/BufferedWriter.close:()V 88: aload_1 89: invokevirtual #20 // Method java/net/ServerSocket.close:()V 92: return } */
练习三:上传文件
- 客户端:数据来自于文本文件
- 服务器:接收到的数据写入文本文件
-
import java.io.*; import java.net.*; public class ClientDemo5 { public static void main(String[] args) throws IOException { Socket s = new Socket("127.0.0.1",10005); BufferedReader br = new BufferedReader(new FileReader("client.txt")); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); String line; while((line = br.readLine()) != null) { bw.write(line); bw.newLine(); bw.flush(); } br.close(); s.close(); } } /** D:\cs>java ClientDemo5 D:\cs>javap -c ClientDemo5 Compiled from "ClientDemo5.java" public class ClientDemo5 { public ClientDemo5(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]) throws java.io.IOException; Code: 0: new #2 // class java/net/Socket 3: dup 4: ldc #3 // String 127.0.0.1 6: sipush 10005 9: invokespecial #4 // Method java/net/Socket."<init>":(Ljava/lang/String;I)V 12: astore_1 13: new #5 // class java/io/BufferedReader 16: dup 17: new #6 // class java/io/FileReader 20: dup 21: ldc #7 // String client.txt 23: invokespecial #8 // Method java/io/FileReader."<init>":(Ljava/lang/String;)V 26: invokespecial #9 // Method java/io/BufferedReader."<init>":(Ljava/io/Reader;)V 29: astore_2 30: new #10 // class java/io/BufferedWriter 33: dup 34: new #11 // class java/io/OutputStreamWriter 37: dup 38: aload_1 39: invokevirtual #12 // Method java/net/Socket.getOutputStream:()Ljava/io/OutputStream; 42: invokespecial #13 // Method java/io/OutputStreamWriter."<init>":(Ljava/io/OutputStream;)V 45: invokespecial #14 // Method java/io/BufferedWriter."<init>":(Ljava/io/Writer;)V 48: astore_3 49: aload_2 50: invokevirtual #15 // Method java/io/BufferedReader.readLine:()Ljava/lang/String; 53: dup 54: astore 4 56: ifnull 76 59: aload_3 60: aload 4 62: invokevirtual #16 // Method java/io/BufferedWriter.write:(Ljava/lang/String;)V 65: aload_3 66: invokevirtual #17 // Method java/io/BufferedWriter.newLine:()V 69: aload_3 70: invokevirtual #18 // Method java/io/BufferedWriter.flush:()V 73: goto 49 76: aload_2 77: invokevirtual #19 // Method java/io/BufferedReader.close:()V 80: aload_1 81: invokevirtual #20 // Method java/net/Socket.close:()V 84: return } */
import java.io.*; import java.net.*; public class ServerDemo5 { public static void main(String[] args) throws IOException { ServerSocket ss = new ServerSocket(10005); Socket s = ss.accept(); BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream())); BufferedWriter bw = new BufferedWriter(new FileWriter("server.txt")); String line; while((line = br.readLine()) != null) { bw.write(line); bw.newLine(); bw.flush(); } bw.close(); ss.close(); } } /** D:\cs>java ServerDemo5 D:\cs>javap -c ServerDemo5 Compiled from "ServerDemo5.java" public class ServerDemo5 { public ServerDemo5(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]) throws java.io.IOException; Code: 0: new #2 // class java/net/ServerSocket 3: dup 4: sipush 10005 7: invokespecial #3 // Method java/net/ServerSocket."<init>":(I)V 10: astore_1 11: aload_1 12: invokevirtual #4 // Method java/net/ServerSocket.accept:()Ljava/net/Socket; 15: astore_2 16: new #5 // class java/io/BufferedReader 19: dup 20: new #6 // class java/io/InputStreamReader 23: dup 24: aload_2 25: invokevirtual #7 // Method java/net/Socket.getInputStream:()Ljava/io/InputStream; 28: invokespecial #8 // Method java/io/InputStreamReader."<init>":(Ljava/io/InputStream;)V 31: invokespecial #9 // Method java/io/BufferedReader."<init>":(Ljava/io/Reader;)V 34: astore_3 35: new #10 // class java/io/BufferedWriter 38: dup 39: new #11 // class java/io/FileWriter 42: dup 43: ldc #12 // String server.txt 45: invokespecial #13 // Method java/io/FileWriter."<init>":(Ljava/lang/String;)V 48: invokespecial #14 // Method java/io/BufferedWriter."<init>":(Ljava/io/Writer;)V 51: astore 4 53: aload_3 54: invokevirtual #15 // Method java/io/BufferedReader.readLine:()Ljava/lang/String; 57: dup 58: astore 5 60: ifnull 83 63: aload 4 65: aload 5 67: invokevirtual #16 // Method java/io/BufferedWriter.write:(Ljava/lang/String;)V 70: aload 4 72: invokevirtual #17 // Method java/io/BufferedWriter.newLine:()V 75: aload 4 77: invokevirtual #18 // Method java/io/BufferedWriter.flush:()V 80: goto 53 83: aload 4 85: invokevirtual #19 // Method java/io/BufferedWriter.close:()V 88: aload_1 89: invokevirtual #20 // Method java/net/ServerSocket.close:()V 92: return } */
练习四:上传文件,并得到服务器的反馈
- 客户端:数据来自于文本文件,接收服务器反馈
- 服务器:接收到的数据写入文本文件,给出反馈
- 出现问题: 程序一直等待
- 原因:读数据的方法是阻塞式的
- 解决方法:1、自定义结束标记;2、使用
shutdownOutput() :禁用此套接字的输出流
(推荐)import java.io.*; import java.net.*; public class ClientDemo6 { public static void main(String[] args) throws IOException { Socket s = new Socket("127.0.0.1",10005); BufferedReader br = new BufferedReader(new FileReader("client.txt")); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); String line; while((line = br.readLine()) != null) { bw.write(line); bw.newLine(); bw.flush(); } s.shutdownOutput(); BufferedReader brClient = new BufferedReader(new InputStreamReader(s.getInputStream())); String data = brClient.readLine(); System.out.println("服务器的反馈:" + data); br.close(); bw.close(); brClient.close(); s.close(); } } /** D:\cs>javac -d . ServerDemo6.java D:\cs>java ServerDemo6 D:\cs>javap -c ServerDemo6 Compiled from "ServerDemo6.java" public class ServerDemo6 { public ServerDemo6(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]) throws java.io.IOException; Code: 0: new #2 // class java/net/ServerSocket 3: dup 4: sipush 10005 7: invokespecial #3 // Method java/net/ServerSocket."<init>":(I)V 10: astore_1 11: aload_1 12: invokevirtual #4 // Method java/net/ServerSocket.accept:()Ljava/net/Socket; 15: astore_2 16: new #5 // class java/io/BufferedReader 19: dup 20: new #6 // class java/io/InputStreamReader 23: dup 24: aload_2 25: invokevirtual #7 // Method java/net/Socket.getInputStream:()Ljava/io/InputStream; 28: invokespecial #8 // Method java/io/InputStreamReader."<init>":(Ljava/io/InputStream;)V 31: invokespecial #9 // Method java/io/BufferedReader."<init>":(Ljava/io/Reader;)V 34: astore_3 35: new #10 // class java/io/BufferedWriter 38: dup 39: new #11 // class java/io/FileWriter 42: dup 43: ldc #12 // String server1.txt 45: invokespecial #13 // Method java/io/FileWriter."<init>":(Ljava/lang/String;)V 48: invokespecial #14 // Method java/io/BufferedWriter."<init>":(Ljava/io/Writer;)V 51: astore 4 53: aload_3 54: invokevirtual #15 // Method java/io/BufferedReader.readLine:()Ljava/lang/String; 57: dup 58: astore 5 60: ifnull 83 63: aload 4 65: aload 5 67: invokevirtual #16 // Method java/io/BufferedWriter.write:(Ljava/lang/String;)V 70: aload 4 72: invokevirtual #17 // Method java/io/BufferedWriter.newLine:()V 75: aload 4 77: invokevirtual #18 // Method java/io/BufferedWriter.flush:()V 80: goto 53 83: new #10 // class java/io/BufferedWriter 86: dup 87: new #19 // class java/io/OutputStreamWriter 90: dup 91: aload_2 92: invokevirtual #20 // Method java/net/Socket.getOutputStream:()Ljava/io/OutputStream; 95: invokespecial #21 // Method java/io/OutputStreamWriter."<init>":(Ljava/io/OutputStream;)V 98: invokespecial #14 // Method java/io/BufferedWriter."<init>":(Ljava/io/Writer;)V 101: astore 6 103: aload 6 105: ldc #22 // String 文件上传成功 107: invokevirtual #16 // Method java/io/BufferedWriter.write:(Ljava/lang/String;)V 110: aload 6 112: invokevirtual #17 // Method java/io/BufferedWriter.newLine:()V 115: aload 6 117: invokevirtual #18 // Method java/io/BufferedWriter.flush:()V 120: aload 4 122: invokevirtual #23 // Method java/io/BufferedWriter.close:()V 125: aload_1 126: invokevirtual #24 // Method java/net/ServerSocket.close:()V 129: aload_2 130: invokevirtual #25 // Method java/net/Socket.close:()V 133: aload_3 134: invokevirtual #26 // Method java/io/BufferedReader.close:()V 137: aload 6 139: invokevirtual #23 // Method java/io/BufferedWriter.close:()V 142: return } */
import java.io.*; import java.net.*; public class ServerDemo6 { public static void main(String[] args) throws IOException { ServerSocket ss = new ServerSocket(10005); Socket s = ss.accept(); BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream())); BufferedWriter bw = new BufferedWriter(new FileWriter("server1.txt")); String line; while((line = br.readLine()) != null) { bw.write(line); bw.newLine(); bw.flush(); } BufferedWriter bwServer = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); bwServer.write("文件上传成功"); bwServer.newLine(); bwServer.flush(); bw.close(); ss.close(); s.close(); br.close(); bwServer.close(); } } /** D:\cs>javac -d . ServerDemo6.java D:\cs>java ServerDemo6 D:\cs>javap -c ServerDemo6 Compiled from "ServerDemo6.java" public class ServerDemo6 { public ServerDemo6(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]) throws java.io.IOException; Code: 0: new #2 // class java/net/ServerSocket 3: dup 4: sipush 10005 7: invokespecial #3 // Method java/net/ServerSocket."<init>":(I)V 10: astore_1 11: aload_1 12: invokevirtual #4 // Method java/net/ServerSocket.accept:()Ljava/net/Socket; 15: astore_2 16: new #5 // class java/io/BufferedReader 19: dup 20: new #6 // class java/io/InputStreamReader 23: dup 24: aload_2 25: invokevirtual #7 // Method java/net/Socket.getInputStream:()Ljava/io/InputStream; 28: invokespecial #8 // Method java/io/InputStreamReader."<init>":(Ljava/io/InputStream;)V 31: invokespecial #9 // Method java/io/BufferedReader."<init>":(Ljava/io/Reader;)V 34: astore_3 35: new #10 // class java/io/BufferedWriter 38: dup 39: new #11 // class java/io/FileWriter 42: dup 43: ldc #12 // String server1.txt 45: invokespecial #13 // Method java/io/FileWriter."<init>":(Ljava/lang/String;)V 48: invokespecial #14 // Method java/io/BufferedWriter."<init>":(Ljava/io/Writer;)V 51: astore 4 53: aload_3 54: invokevirtual #15 // Method java/io/BufferedReader.readLine:()Ljava/lang/String; 57: dup 58: astore 5 60: ifnull 83 63: aload 4 65: aload 5 67: invokevirtual #16 // Method java/io/BufferedWriter.write:(Ljava/lang/String;)V 70: aload 4 72: invokevirtual #17 // Method java/io/BufferedWriter.newLine:()V 75: aload 4 77: invokevirtual #18 // Method java/io/BufferedWriter.flush:()V 80: goto 53 83: new #10 // class java/io/BufferedWriter 86: dup 87: new #19 // class java/io/OutputStreamWriter 90: dup 91: aload_2 92: invokevirtual #20 // Method java/net/Socket.getOutputStream:()Ljava/io/OutputStream; 95: invokespecial #21 // Method java/io/OutputStreamWriter."<init>":(Ljava/io/OutputStream;)V 98: invokespecial #14 // Method java/io/BufferedWriter."<init>":(Ljava/io/Writer;)V 101: astore 6 103: aload 6 105: ldc #22 // String 文件上传成功 107: invokevirtual #16 // Method java/io/BufferedWriter.write:(Ljava/lang/String;)V 110: aload 6 112: invokevirtual #17 // Method java/io/BufferedWriter.newLine:()V 115: aload 6 117: invokevirtual #18 // Method java/io/BufferedWriter.flush:()V 120: aload 4 122: invokevirtual #23 // Method java/io/BufferedWriter.close:()V 125: aload_1 126: invokevirtual #24 // Method java/net/ServerSocket.close:()V 129: aload_2 130: invokevirtual #25 // Method java/net/Socket.close:()V 133: aload_3 134: invokevirtual #26 // Method java/io/BufferedReader.close:()V 137: aload 6 139: invokevirtual #23 // Method java/io/BufferedWriter.close:()V 142: return } */
练习五:服务器可以接收多个客户端上传的文件,线程封装
- 客户端: 数据来自文本文件,接收服务器反馈
- 服务器:接收到的数据写入文本文件,给出反馈,代码用线程封装,为每一个客户端开启一个线程
-
import java.io.*; import java.net.*; public class ClientDemo7 { public static void main(String[] args) throws IOException { Socket s = new Socket("127.0.0.1",10005); BufferedReader br = new BufferedReader(new FileReader("clientDemo.txt")); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); String line; while((line = br.readLine()) != null) { bw.write(line); bw.newLine(); bw.flush(); } s.shutdownOutput(); BufferedReader brClient = new BufferedReader(new InputStreamReader(s.getInputStream())); String data = brClient.readLine(); System.out.println("服务器的反馈:" + data); br.close(); bw.close(); brClient.close(); s.close(); } } /** D:\cs>java ClientDemo7 服务器的反馈:文件上传成功 D:\cs>java ClientDemo7 服务器的反馈:文件上传成功 D:\cs>javap -c ClientDemo7 Compiled from "ClientDemo7.java" public class ClientDemo7 { public ClientDemo7(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]) throws java.io.IOException; Code: 0: new #2 // class java/net/Socket 3: dup 4: ldc #3 // String 127.0.0.1 6: sipush 10005 9: invokespecial #4 // Method java/net/Socket."<init>":(Ljava/lang/String;I)V 12: astore_1 13: new #5 // class java/io/BufferedReader 16: dup 17: new #6 // class java/io/FileReader 20: dup 21: ldc #7 // String clientDemo.txt 23: invokespecial #8 // Method java/io/FileReader."<init>":(Ljava/lang/String;)V 26: invokespecial #9 // Method java/io/BufferedReader."<init>":(Ljava/io/Reader;)V 29: astore_2 30: new #10 // class java/io/BufferedWriter 33: dup 34: new #11 // class java/io/OutputStreamWriter 37: dup 38: aload_1 39: invokevirtual #12 // Method java/net/Socket.getOutputStream:()Ljava/io/OutputStream; 42: invokespecial #13 // Method java/io/OutputStreamWriter."<init>":(Ljava/io/OutputStream;)V 45: invokespecial #14 // Method java/io/BufferedWriter."<init>":(Ljava/io/Writer;)V 48: astore_3 49: aload_2 50: invokevirtual #15 // Method java/io/BufferedReader.readLine:()Ljava/lang/String; 53: dup 54: astore 4 56: ifnull 76 59: aload_3 60: aload 4 62: invokevirtual #16 // Method java/io/BufferedWriter.write:(Ljava/lang/String;)V 65: aload_3 66: invokevirtual #17 // Method java/io/BufferedWriter.newLine:()V 69: aload_3 70: invokevirtual #18 // Method java/io/BufferedWriter.flush:()V 73: goto 49 76: aload_1 77: invokevirtual #19 // Method java/net/Socket.shutdownOutput:()V 80: new #5 // class java/io/BufferedReader 83: dup 84: new #20 // class java/io/InputStreamReader 87: dup 88: aload_1 89: invokevirtual #21 // Method java/net/Socket.getInputStream:()Ljava/io/InputStream; 92: invokespecial #22 // Method java/io/InputStreamReader."<init>":(Ljava/io/InputStream;)V 95: invokespecial #9 // Method java/io/BufferedReader."<init>":(Ljava/io/Reader;)V 98: astore 5 100: aload 5 102: invokevirtual #15 // Method java/io/BufferedReader.readLine:()Ljava/lang/String; 105: astore 6 107: getstatic #23 // Field java/lang/System.out:Ljava/io/PrintStream; 110: aload 6 112: invokedynamic #24, 0 // InvokeDynamic #0:makeConcatWithConstants:(Ljava/lang/String;)Ljava/lang/String; 117: invokevirtual #25 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 120: aload_2 121: invokevirtual #26 // Method java/io/BufferedReader.close:()V 124: aload_3 125: invokevirtual #27 // Method java/io/BufferedWriter.close:()V 128: aload 5 130: invokevirtual #26 // Method java/io/BufferedReader.close:()V 133: aload_1 134: invokevirtual #28 // Method java/net/Socket.close:()V 137: return } */
import java.net.*; import java.io.*; public class ServerThread7 implements Runnable { private Socket s; public ServerThread7(Socket s) { this.s = s; } @Override public void run() { try { BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream())); int count = 0; File file = new File("serverDemo[" + count + "].txt"); while(file.exists()) { count++; file = new File("serverDemo[" + count + "].txt"); } BufferedWriter bw = new BufferedWriter(new FileWriter(file)); String line; while((line = br.readLine()) != null) { bw.write(line); bw.newLine(); bw.flush(); } BufferedWriter bwServer = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); bwServer.write("文件上传成功"); bwServer.newLine(); bwServer.flush(); s.close(); } catch (IOException e) { e.printStackTrace(); } } } /** D:\cs>javap -c ServerThread7 Compiled from "ServerThread7.java" public class ServerThread7 implements java.lang.Runnable { public ServerThread7(java.net.Socket); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: aload_0 5: aload_1 6: putfield #2 // Field s:Ljava/net/Socket; 9: return public void run(); Code: 0: new #3 // class java/io/BufferedReader 3: dup 4: new #4 // class java/io/InputStreamReader 7: dup 8: aload_0 9: getfield #2 // Field s:Ljava/net/Socket; 12: invokevirtual #5 // Method java/net/Socket.getInputStream:()Ljava/io/InputStream; 15: invokespecial #6 // Method java/io/InputStreamReader."<init>":(Ljava/io/InputStream;)V 18: invokespecial #7 // Method java/io/BufferedReader."<init>":(Ljava/io/Reader;)V 21: astore_1 22: iconst_0 23: istore_2 24: new #8 // class java/io/File 27: dup 28: iload_2 29: invokedynamic #9, 0 // InvokeDynamic #0:makeConcatWithConstants:(I)Ljava/lang/String; 34: invokespecial #10 // Method java/io/File."<init>":(Ljava/lang/String;)V 37: astore_3 38: aload_3 39: invokevirtual #11 // Method java/io/File.exists:()Z 42: ifeq 65 45: iinc 2, 1 48: new #8 // class java/io/File 51: dup 52: iload_2 53: invokedynamic #9, 0 // InvokeDynamic #0:makeConcatWithConstants:(I)Ljava/lang/String; 58: invokespecial #10 // Method java/io/File."<init>":(Ljava/lang/String;)V 61: astore_3 62: goto 38 65: new #12 // class java/io/BufferedWriter 68: dup 69: new #13 // class java/io/FileWriter 72: dup 73: aload_3 74: invokespecial #14 // Method java/io/FileWriter."<init>":(Ljava/io/File;)V 77: invokespecial #15 // Method java/io/BufferedWriter."<init>":(Ljava/io/Writer;)V 80: astore 4 82: aload_1 83: invokevirtual #16 // Method java/io/BufferedReader.readLine:()Ljava/lang/String; 86: dup 87: astore 5 89: ifnull 112 92: aload 4 94: aload 5 96: invokevirtual #17 // Method java/io/BufferedWriter.write:(Ljava/lang/String;)V 99: aload 4 101: invokevirtual #18 // Method java/io/BufferedWriter.newLine:()V 104: aload 4 106: invokevirtual #19 // Method java/io/BufferedWriter.flush:()V 109: goto 82 112: new #12 // class java/io/BufferedWriter 115: dup 116: new #20 // class java/io/OutputStreamWriter 119: dup 120: aload_0 121: getfield #2 // Field s:Ljava/net/Socket; 124: invokevirtual #21 // Method java/net/Socket.getOutputStream:()Ljava/io/OutputStream; 127: invokespecial #22 // Method java/io/OutputStreamWriter."<init>":(Ljava/io/OutputStream;)V 130: invokespecial #15 // Method java/io/BufferedWriter."<init>":(Ljava/io/Writer;)V 133: astore 6 135: aload 6 137: ldc #23 // String 文件上传成功 139: invokevirtual #17 // Method java/io/BufferedWriter.write:(Ljava/lang/String;)V 142: aload 6 144: invokevirtual #18 // Method java/io/BufferedWriter.newLine:()V 147: aload 6 149: invokevirtual #19 // Method java/io/BufferedWriter.flush:()V 152: aload_0 153: getfield #2 // Field s:Ljava/net/Socket; 156: invokevirtual #24 // Method java/net/Socket.close:()V 159: goto 167 162: astore_1 163: aload_1 164: invokevirtual #26 // Method java/io/IOException.printStackTrace:()V 167: return Exception table: from to target type 0 159 162 Class java/io/IOException } */
import java.io.*; import java.net.*; public class ServerDemo7 { public static void main(String[] args) throws IOException { ServerSocket ss = new ServerSocket(10005); while(true) { Socket s = ss.accept(); new Thread(new ServerThread7(s)).start(); } } } /** D:\cs>javap -c ServerDemo7 Compiled from "ServerDemo7.java" public class ServerDemo7 { public ServerDemo7(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]) throws java.io.IOException; Code: 0: new #2 // class java/net/ServerSocket 3: dup 4: sipush 10005 7: invokespecial #3 // Method java/net/ServerSocket."<init>":(I)V 10: astore_1 11: aload_1 12: invokevirtual #4 // Method java/net/ServerSocket.accept:()Ljava/net/Socket; 15: astore_2 16: new #5 // class java/lang/Thread 19: dup 20: new #6 // class ServerThread7 23: dup 24: aload_2 25: invokespecial #7 // Method ServerThread7."<init>":(Ljava/net/Socket;)V 28: invokespecial #8 // Method java/lang/Thread."<init>":(Ljava/lang/Runnable;)V 31: invokevirtual #9 // Method java/lang/Thread.start:()V 34: goto 11 } */