网络编程(二十)


网络编程(二十)

网络编程:计算机与计算机之间通过网络进行数据传输。

Java中可以使用java.net包下的技术开发出常见的网络应用程序。

常见的软件架构

CS

CS,Client/Server,客户端/服务器,在用户本地需要下载并安装客户端程序,在远程有一个服务器端程序。

通过客户端访问服务器。

适合定制专业化的办公类软件,例如:IDEA,网游

优点

  1. 快速响应:由于客户端和服务端的分工协作,能够迅速响应用户请求,提供更快的响应速度。
  2. 功能复杂:客户端可以在响应服务端的同时执行一些处理逻辑,提供更加完整的功能。
  3. 易于维护:由于各模块分工明确,每个模块可以独立开发,便于管理和维护。

缺点

  1. 成本高:客户端和服务端需要独立开发和管理,所需人力物力较多。

  2. 安全性差:由于客户端和服务端之间的通信频繁,增加了被攻击的风险。

BS

BS,Brower/Server,浏览器/服务器,只需要一个浏览器,用户通过不同的网址,客户访问不同的服务器。

通过浏览器访问服务器。

适合移动互联网应用,可以在任何地方任何时间访问的系统。

优点

  1. 低成本:相比于CS架构,BS架构只需服务端部分进行专门的开发,降低了成本。
  2. 易于维护:应用逻辑全部集中在服务端,便于后台管理。
  3. 安全性高:由于所有操作都在服务器端进行,可以减少安全隐患,实现较高的防御能力。

缺点

  1. 响应速度慢:由于服务器承担了所有的计算和存储任务,文件的传输和页面的刷新等耗时的操作都需要等待服务器完成,这可能导致用户体验不佳。
  2. 功能不足:由于大多数处理逻辑都在服务器端完成,用户可能无法获得完整的用户体验。

网络编程三要素

  1. IP:设备在网络中的地址,是唯一的标识
  2. 端口号:应用程序在设备中唯一的标识
  3. 协议:数据在网络中传输的规则,常见的协议有UDP,TCP,http,https,ftp

IP

全称:Internet Protocol,是互联网协议地址,也称IP地址,是分配给上网设备的数字标签,即上网设备在网络中的地址,是唯一的。

常见IP分类:IPv4,IPv6

IPv4

全称:Internet Protocol Version 4,互联网通信协议第四版,采用32位地址长度,分为4组,每组8位二进制数。

可利用点分十进制表示法来表示。

目前的主流方案,最多只有2^32次方个IP,目前已经用完,现在利用局域网IP解决IP不够的问题。

IPv4的地址分类形式:

  • 公网地址(万维网使用)和私有地址(局域网使用)
  • 192.168.开头代表的就是私有地址,范围为192.168.0.0-192.168.255.255,专门为组织机构内部使用,以此节省IP。

特殊IP地址:127.0.0.1,也可以是localhost,是回送地址也称本地回环地址,也称本机IP,永远只会寻找当前所在本机。

IPv6

全称:Internet Protocol Version 6,互联网通信协议第六版,采用128位地址长度,分为8组,每组16位二进制数。

可利用冒分十六进制表示法

最多有2^128次方个IP。

端口号

由两个字节表示的整数,取值范围:0-65535

其中0-1023之间的端口用于一些知名的网络服务或应用,我们自己使用1024以上的端口号就可以了。

:一个端口号只能被一个应用程序使用

协议

计算机网络中,连接和通信的规则被称为网络通信协议。

  • OSI参考模型:世界互联协议标准,全球通信规范,单模型过于理想化,未在因特网上进行广泛传播
    • 应用层
    • 表示层
    • 会话层
    • 传输层
    • 网路层
    • 数据链路层
    • 物理层
  • TCP/IP参考模型:或TCP/IP协议,事实上的国际标准
    • 应用层:HTTP,FTP,Telnet,DNS…
    • 传输层:TCP,UDP…
    • 网络互联层:IP,ICMP,ARP…
    • 网络接入层:硬件设备0101010….

UDP协议

用户数据报协议,User Datagram Protocol

UDP是面向无连接(不管是否连接成功)的通信协议。

速度快,有大小限制,一次最多发64K,数据不安全,易丢失数据。

TCP协议

传输控制协议,Transmission Control Protocol

TCP协议是面向连接(确保连接成功)的通信协议。

速度慢,无大小限制,数据安全。

InetAddress类

此类表示互联网协议(IP)的地址,该类并未对外提供构造方法,需要通过静态方法getByName获取对象。

InetAddress有两个子类:Inet4Address,Inet6Address

getByName方法会判断是使用的IPv4还是IPv6。

若是IPv4则会创建Inet4Address对象进行返回。

若是IPv6则会创建Inet6Address对象进行返回。

常用方法

getByName

格式

static InetAddress getByName(String host)

说明:确定主机名称的IP地址,主机名称可以是机器名称,也可以是IP地址。

getHostName

格式

String getHostName()

说明:获取此IP地址的主机名

getHostAddress

格式

String getHostAddress()

说明:返回文本显示中的IP地址字符串

范例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import java.net.InetAddress;
import java.net.UnknownHostException;

public class Test {
public static void main(String[] args) throws UnknownHostException {
InetAddress address1=InetAddress.getByName("192.168.19.1");
System.out.println(address1);//打印出 /IP地址
System.out.println(address1.getHostAddress());//打印出IP地址
System.out.println(address1.getHostName());//打印出设备名称

System.out.println();
InetAddress address2=InetAddress.getByName("DESKTOP-FAEF9UU");
System.out.println(address2);//打印出 设备名/IP地址
System.out.println(address2.getHostAddress());//打印出IP地址
System.out.println(address2.getHostName());//打印出设备名称
}
}

UDP通信程序

发送数据

步骤

  1. 创建发送端的DatagramSocket对象
    • 绑定端口,以后我们就是通过这个端口往外发送
    • 空参:所有可用的端口中随机一个进行使用
    • 有参:指定端口号进行使用
  2. 数据打包DatagramPacket
  3. 发送数据
  4. 释放资源

接收数据

步骤

  1. 创建接收端的DatagramSocket对象
  2. 接收打包好的数据
  3. 解析数据包
  4. 释放资源

范例1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//必须先执行接收文件,再执行发送文件
//ReceiveMessageDemo.java
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class ReceiveMessageDemo {
public static void main(String[] args) throws IOException {
DatagramSocket ds=new DatagramSocket(10086);

byte[] bytes=new byte[1024];
DatagramPacket dp=new DatagramPacket(bytes,bytes.length);
ds.receive(dp);

byte[] data=dp.getData();
int length=dp.getLength();
InetAddress address =dp.getAddress();
int port=dp.getPort();
System.out.println("接收到数据"+new String(data,0,length));
System.out.println("该数据是从"+address+"电脑中端口为"+port+"的位置发出");

ds.close();
}
}
/*
接收到数据你好
该数据是从/127.0.0.1电脑中端口为52727的位置发出
*/

//SendMessageDemo.java
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class SendMessageDemo {
public static void main(String[] args) throws IOException {
//1.创建DatagramSocket对象
DatagramSocket ds=new DatagramSocket();

//2.打包数据
InetAddress address=InetAddress.getByName("127.0.0.1");
String s="你好";
byte[] bytes=s.getBytes();
int port=10086;
DatagramPacket dp=new DatagramPacket(bytes,bytes.length,address,port);
//3.发送数据
ds.send(dp);
//4.释放数据
ds.close();
}
}

范例2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
//按照下面的要求实现程序
//UDP发送数据:数据来自于键盘录入,直到输入的数据是886,发送数据结束
//UDP接收数据:因为接收端不知道发送端什么时候停止,故采用死循环
//SendMessageDemo.java
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;

public class SendMessageDemo {
public static void main(String[] args) throws IOException {
DatagramSocket ds=new DatagramSocket();
Scanner sc=new Scanner(System.in);
while (true) {
System.out.print("请输入你要传输的数据:");
String s=sc.nextLine();
byte[] bytes=s.getBytes();
InetAddress address=InetAddress.getByName("127.0.0.1");
int port=10086;
DatagramPacket dp=new DatagramPacket(bytes,bytes.length,address,port);
ds.send(dp);
if(s.equals("886")){
System.out.println("通讯结束");
break;
}
}
ds.close();
}
}

//ReceiveMessageDemo.java
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class ReceiveMessageDemo {
public static void main(String[] args) throws IOException {
DatagramSocket ds=new DatagramSocket(10086);
byte[] bytes = new byte[1024];
DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
while(true){
ds.receive(dp);
int port = dp.getPort();
String address = dp.getAddress().getHostAddress();
String name = dp.getAddress().getHostName();
byte[] data = dp.getData();
int len = dp.getLength();
System.out.println("接收到数据:");
String s = new String(data, 0, len);
System.out.println(s);
System.out.println("该数据来自" + address + "主机名"+name+"端口为" + port + "的位置");
}
}
}

通信方式

  1. 单播:只给一个网络设备发送数据,之前的两个范例便时单播
  2. 组播:给一组网络设备发送数据
    • 组播地址:224.0.0.0-239.255.255.255,其中224.0.0.0-224.0.0.255为预留的组播地址
    • 组播接收端:不创建DatagramSocket对象,而需要创建MulticastSocket对象,且需要将当前本机添加到指定组中
    • 组播发送端:不创建DatagramSocket对象,而需要创建MulticastSocket对象,需将目的地址改成组播地址
  3. 广播:给局域网内所有网络设备发送数据
    • 广播地址:255.255.255.255
    • 和单播大致没区别,只需要把地址目的地址改为255.255.255.0

组播范例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
//SendMessageDemo.java
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.util.Scanner;

public class SendMessageDemo {
public static void main(String[] args) throws IOException {
MulticastSocket ms=new MulticastSocket();
System.out.print("请输入数据:");
Scanner sc=new Scanner(System.in);
String s=sc.nextLine();
byte[] bytes=s.getBytes();
InetAddress address=InetAddress.getByName("224.0.0.1");
int port=10086;
DatagramPacket dp=new DatagramPacket(bytes,bytes.length,address,port);
ms.send(dp);
ms.close();
}
}

//ReceiveMessageDemo1.java
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;

public class ReceiveMessageDemo1 {
public static void main(String[] args) throws IOException {
MulticastSocket ms=new MulticastSocket(10086);

InetAddress address=InetAddress.getByName("224.0.0.1");
ms.joinGroup(address);

byte[] bytes=new byte[1024];
DatagramPacket dp=new DatagramPacket(bytes,bytes.length);
ms.receive(dp);

int port=dp.getPort();
String sendAddress=dp.getAddress().getHostAddress();
String sendName=dp.getAddress().getHostName();
int len=dp.getLength();
byte[] data = dp.getData();
String s = new String(data, 0, len);
System.out.println(s);
System.out.println("该数据来自" + sendAddress + "主机名"+sendName+"端口为" + port + "的位置");

ms.close();
}
}

//ReceiveMessageDemo2.java
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;

public class ReceiveMessageDemo2 {
public static void main(String[] args) throws IOException {
MulticastSocket ms=new MulticastSocket(10086);

InetAddress address=InetAddress.getByName("224.0.0.1");
ms.joinGroup(address);

byte[] bytes=new byte[1024];
DatagramPacket dp=new DatagramPacket(bytes,bytes.length);
ms.receive(dp);

int port=dp.getPort();
String sendAddress=dp.getAddress().getHostAddress();
String sendName=dp.getAddress().getHostName();
int len=dp.getLength();
byte[] data = dp.getData();
String s = new String(data, 0, len);
System.out.println(s);
System.out.println("该数据来自" + sendAddress + "主机名"+sendName+"端口为" + port + "的位置");

ms.close();
}
}

广播范例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
//SendMessageDemo.java
import java.io.IOException;
import java.net.*;
import java.util.Scanner;

public class SendMessageDemo {
public static void main(String[] args) throws IOException {
DatagramSocket ds=new DatagramSocket();

Scanner sc=new Scanner(System.in);
System.out.print("请输入数据:");
String s=sc.nextLine();
byte[] bytes=s.getBytes();
InetAddress address=InetAddress.getByName("255.255.255.255");
int port=10086;
DatagramPacket dp=new DatagramPacket(bytes,bytes.length,address,port);
ds.send(dp);
ds.close();

}
}

//ReceiveMessageDemo1.java
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class ReceiveMessageDemo1 {
public static void main(String[] args) throws IOException {
DatagramSocket ds=new DatagramSocket(10086);
byte[] bytes = new byte[1024];
DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
ds.receive(dp);
int port = dp.getPort();
String address = dp.getAddress().getHostAddress();
String name = dp.getAddress().getHostName();
byte[] data = dp.getData();
int len = dp.getLength();
System.out.println("接收到数据:");
String s = new String(data, 0, len);
System.out.println(s);
System.out.println("该数据来自" + address + "主机名"+name+"端口为" + port + "的位置");
}
}

TCP通信程序

TCP通信协议是一种可靠的网络协议,它在通信的两端各建立一个Socket对象。

通信之前要保证连接已经建立。

通过Socket产生IO流来进行网络通信。

三次握手

  1. 客户端向服务器发出连接请求,等待服务器确认
  2. 服务器向客户端返回一个响应,告诉客户端收到了请求
  3. 客户端向服务器再次发出确认信息,连接建立

四次挥手

  1. 客户端向服务器发出取消连接请求
  2. 服务器向客户端返回一个响应,表示收到客户端取消请求,随后服务器将最后的数据处理完毕。
  3. 服务器向客户端发送确认取消信息
  4. 客户端再次发送确认信息,连接取消

代码思路

客户端

  1. 创建客户的Socket对象(Socket)与指定服务端连接,三次握手协议保证连接建立,若连接不上,代码会报错
    • Socket(String host,int port)
  2. 获取输出流,写数据
    • OutputStream getOutputStream()
  3. 释放资源,利用四次挥手协议断开连接,且确保连接通道里的数据已经处理完毕
    • void close()

服务器

  1. 创建服务端的Socket对象(ServerSocket)
    • ServerSocket(int port)
  2. 监听客户单连接,返回一个Socket对象
    • Socket accept()
  3. 获取输入流,读数据,并把数据显示在控制台
    • InputStream getInputStream
  4. 释放资源
    • void close()

范例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//需要先运行服务端
//client.java
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;

public class Client {
public static void main(String[] args) throws IOException {
Socket socket=new Socket("127.0.0.1",10086);
String s="hello!你好!";
OutputStream os=socket.getOutputStream();
os.write(s.getBytes());
os.close();
socket.close();
}
}

//Server.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
public static void main(String[] args) throws IOException {
ServerSocket ss=new ServerSocket(10086);
Socket accept = ss.accept();
BufferedReader br=new BufferedReader(new InputStreamReader(accept.getInputStream()));
int ch;
while((ch=br.read())!=-1){
System.out.print((char)ch);
}
br.close();
accept.close();
ss.close();
}
}

范例

例1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
//多发多收
//客户端:多次发送数据
//服务器多次接收数据,并打印
//Client.java
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;

public class Client {
public static void main(String[] args) throws IOException {
Socket socket=new Socket("127.0.0.1",10086);
Scanner sc=new Scanner(System.in);
OutputStream os=socket.getOutputStream();
while (true) {
System.out.print("请输入数据:");
String s=sc.nextLine();
if(s.equals("886")){
break;
}
os.write(s.getBytes());
}
socket.close();
}
}
//Server.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
public static void main(String[] args) throws IOException {
ServerSocket ss=new ServerSocket(10086);
Socket socket=ss.accept();
BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
int ch;
while((ch=br.read())!=-1){
System.out.print((char)ch);
}
socket.close();
ss.close();
}
}

/*client的运行
请输入数据:saf
请输入数据:453
请输入数据:996
请输入数据:886
*/
/*Server的运行
saf453996
*/

例2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
//接收与反馈
//客户端:发送一条消息,接收服务端反馈的消息并打印
//服务器:接收数据并打印,在给客户端反馈消息

//Server.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
public static void main(String[] args) throws IOException {
//1.创建对象并绑定10086接口
ServerSocket ss=new ServerSocket(10086);
//2.等待客户端连接
Socket s=ss.accept();
//3.socket中获取输入流读取数据
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
int ch;
//细节:read方法会从接连通道中读取数据
//需要有一个结束标记,此处循环才会停止
//程序就会一直挺爱read方法这里,等待读取下面的数据
while ((ch=br.read())!=-1){
System.out.print((char)ch);
}
//4.回写数据
OutputStream os = s.getOutputStream();
os.write("服务端已收到消息".getBytes());
//5.释放资源
s.close();
ss.close();
}
}
//Client.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;

public class Client {
public static void main(String[] args) throws IOException {
//1.创建socket对象连接客户端
Socket s=new Socket("127.0.0.1",10086);
//2.写出数据
OutputStream os = s.getOutputStream();
os.write("你好".getBytes());
//3.写出一个结束标记
s.shutdownOutput();

//4.接收服务端回写的数据
BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream()));
int ch;
while ((ch=br.read())!=-1){
System.out.print((char)ch);
}
//5.释放资源
os.close();
}
}
/*Server收到的消息
你好
*/
/*Client发送的消息
服务端已收到消息
*/

例3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
//上传文件
//客户端:将本地文件上传到服务器,接收服务器的反馈
//服务器:接收客户端上传的文件,上传完毕后给出反馈
//服务器接收后文件是唯一的,每次接收的内容一样,文件名不一样
//利用UUID类的randomUUID方法实现,UUID表示通用唯一标识符UUID类,UUID表示一个128位的值)
//Server.java
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.UUID;

public class Server {
public static void main(String[] args) throws IOException {
ServerSocket ss=new ServerSocket(10086);
Socket accept = ss.accept();
BufferedInputStream bis = new BufferedInputStream(accept.getInputStream());
String name= UUID.randomUUID().toString().replace("-","");
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("serverphoto\\"+name+".jpg"));
byte[] bytes=new byte[1024];
int len;
while((len=bis.read(bytes))!=-1){
bos.write(bytes,0,len);
}
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(accept.getOutputStream()));
bw.write("上传成功");
bw.newLine();
bw.close();
bos.close();
accept.close();
ss.close();
}
}
//Client.java
import java.io.*;
import java.net.Socket;

public class Client {
public static void main(String[] args) throws IOException {
Socket s=new Socket("127.0.0.1",10086);
BufferedInputStream bis=new BufferedInputStream(new FileInputStream("clientphoto\\photo.jpg"));
BufferedOutputStream bos = new BufferedOutputStream(s.getOutputStream());
byte[] bytes=new byte[1024];
int len;
while((len=bis.read(bytes))!=-1){
bos.write(bytes,0,len);
}
bos.flush();
s.shutdownOutput();
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String str=br.readLine();
System.out.println(str);
br.close();
bis.close();
s.close();
}
}

例4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
//上传文件(多线程版)
//若服务器不停止,能接收很多用户上传的图片
//提示:可用循环或多线程,但循环不合理,最优解法(循环+多线程+线程池)改写
//Server.java
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class Server {
public static void main(String[] args) throws IOException {
ThreadPoolExecutor pool=new ThreadPoolExecutor(
3,
16,
60,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(2),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy()
);
ServerSocket ss=new ServerSocket(10086);
while (true) {
Socket accept=ss.accept();
pool.execute(new MyRunnable(accept));
}
}
}
//Client.java
import java.io.*;
import java.net.Socket;

public class Client {
public static void main(String[] args) throws IOException {
Socket s=new Socket("127.0.0.1",10086);
BufferedInputStream bis=new BufferedInputStream(new FileInputStream("clientphoto\\photo.jpg"));
BufferedOutputStream bos = new BufferedOutputStream(s.getOutputStream());
byte[] bytes=new byte[1024];
int len;
while((len=bis.read(bytes))!=-1){
bos.write(bytes,0,len);
}
bos.flush();
s.shutdownOutput();
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String str=br.readLine();
System.out.println(str);
br.close();
bis.close();
s.close();
}
}

例5

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//BS,接收浏览器的消息并打印
//无需写客户端
//服务器:接收数据并打印
//在浏览器搜索 127.0.0.1:端口号
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
public static void main(String[] args) throws IOException {
ServerSocket ss=new ServerSocket(10086);
Socket accept = ss.accept();
InputStreamReader isr = new InputStreamReader(accept.getInputStream());

int ch;
while ((ch=isr.read())!=-1){
System.out.print((char)ch);
}
accept.close();
ss.close();

}
}

Author: ljs
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint polocy. If reproduced, please indicate source ljs !
评论
  TOC