Java网络编程

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
    }
    */

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值