JAVA-网络编程应用实例
网络编程三要素
协议
网络通信协议
IP地址
在网络中用许多计算机,IP地址作为计算机的唯一标识。
端口
每个软件对应的标识。两个字节表示。范围在0-65535之间。前1024一般不用,已经指定给其他的软件。
TCP通信步骤
- 服务器先启动
- 服务器不会主动请求客户端,必须使用客户端请求服务器端。
- 客户端与服务器端建立连接后,在连接中会创建一个IO对象
- 客户端与服务端就可以通过这个IO对象来进行通信
- 通信的数据不仅仅是字符,所以创建的IO对象是字节流对象。

服务器端必须明确两件事
- 多个客户端和服务器进行交互时,服务器要知道是哪个客户端和自己交互。所以在服务器端提供了一个acceot()方法获取到客户端请求的对象。
- 多个客户端跟服务器端进行交流时,就要使用多个IO流对象。但是在服务器端并没有IO对象,而是使用客户端的流对象。
TCP通信示例-java
/*
tcp通信客户端:向服务器端发送请求,给服务器发送数据,读取服务器回写的数据
表示客户端的对象:java.net中Socket对象;此类对象实现了客户端套接字。套接字中应包含服务器的IP地址值与端口号
构造方法:Socket(String host, int port) 创建流套接字并将其连接到指定主机上的指定端口号。
参数:String host 服务器主机的名称/IP地址
int port 服务器的端口号
成员方法:InputStream getInputStream() 返回此套接字的输入流。
OutputStream getOutputStream() 返回此套接字的输出流。
void close() 释放资源
实现步骤:
1.创建一个客户端对象Socket,构造方法绑定服务器的IP地址和端口号。
2.使用成员方法对象getOutputStream()获取网络字节输出流对象OutputStream
3.使用OutputStream对象中方法write()方法向服务器端发送数据。
4.使用成员方法对象getInputStream() 获取网络字节输入流对象InputStream
5.使用InputStream对象中方法read()方法读取数据。
6.释放资源(Socket.close)
注意:
1.客户端与服务端在进行交互时,只能使用Socket中提供的网络流,服务器端不能创建自己的流对象
2.当我们创建客户端对象Socket时,就会请求服务器并且和服务器建立3次握手后建立连接通路。如果服务器没有正常启动,那么就会抛出异常。
如果服务器已经启动,那么连接成功,可以进行交互。
*/
package 网络通信;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class TCPClient {
public static void main(String[] args) throws IOException {
//创建一个客户端对象Socket
Socket client=new Socket("127.0.0.1",8888);
//使用成员方法对象getOutputStream()获取网络字节输出流对象OutputStream
OutputStream os = client.getOutputStream();
os.write("你好服务器".getBytes());
//使用成员方法对象getInputStream() 获取网络字节输入流对象InputStream
InputStream input = client.getInputStream();
//使用InputStream对象中方法read()方法读取数据。
byte[] bytes=new byte[1024];
int len=input.read(bytes);
System.out.println(new String(bytes,0,len));
//6.释放资源(Socket)
client.close();
}
}
-------------------------------------------------------
//服务器端
/*
服务器端:接收客户端的请求;接受客户端的数据;向客户端回写数据
ServerSocket 这个类实现了服务器套接字
构造方法:ServerSocket(int port) 创建绑定到指定端口的服务器套接字。
服务器端必须明确一件事情,必须找到那个客户端在请求它。使用accept()方法。
成员方法:Socket accept() 侦听要连接到此套接字并接受它 ,返回值为Socket对象。
服务器实现步骤:
1.创建服务器Server对象和系统要指定的端口号。
2.使用成员方法accept(),获取到请求的客户端。
3.使用成员方法对象getInputStream() 获取网络字节输入流对象InputStream
4.使用InputStream对象中方法read()方法读取客户端数据。
5.使用成员方法对象getOutputStream()获取网络字节输出流对象OutputStream
6.使用OutputStream对象中方法write()方法向客户端回送数据。
7.释放资源(Socket,ServerSocket)
*/
package 网络通信;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPServer {
public static void main(String[] args) throws IOException {
//1.创建服务器Server对象和系统要指定的端口号。
ServerSocket Server=new ServerSocket(8888);
//2.使用成员方法accept(),获取到请求的客户端。
Socket so = Server.accept();
//3.使用成员方法对象getInputStream() 获取网络字节输入流对象InputStream
InputStream input = so.getInputStream();
//4.使用InputStream对象中方法read()方法读取客户端数据。
byte[] bytes=new byte[1024];
int len=input.read(bytes);
System.out.println(new String(bytes,0,len));
//5.使用成员方法对象getOutputStream()获取网络字节输出流对象OutputStream
OutputStream output = so.getOutputStream();
//6.使用OutputStream对象中方法write()方法向客户端回送数据。
output.write("谢谢收到".getBytes());
//7.释放资源(Socket,ServerSocket)
so.close();
Server.close();
}
}
TCP文件上传案例

原理:客户端从本地上传读取文件,把文件上传到服务器,服务器把上传的文件保存到服务器的硬盘上。
步骤分析
- 客户端使用本地字节输入流读取上传的文件
- 客户端使用网络字节输出流,把读取到文件上传到服务器
- 服务器端使用网络输入流对象,读取客户端上传的文件
- 服务器端创建本地输出流,将文件存储到服务器本地文件
- 服务器使用网络字节输出流,给客户端会送一个“上传成功”
- 客户端使用网络字节输入流,读取服务器写的数据。
注意:客户端和服务器端在本地对硬盘读取与存入时,需要使用自己创建的输入、输出流:客户端与服务器端在进行网络通信时,必须使用Socket对象中输入、输出流。
文件的上传原理:是对文件的复制;必须明确 数据源 数据的目的地。

-----------------------------------------------
//客户端
/*
实现步骤:
1.创建一个本地字节输入流FiLeInputstream对象,构造方法中绑定要读取的数据源
2.创建一个客户端Socket对象,构造方法中绑定服务器的IP地址和端口号
3.使用Socket中的方法getoutputstream,获取网络字节输出流OutputStream对象
4.使用本地字节输入流FileInputstream对家中的方法read,读职本地文件
5.使用网络字节输出流Outputstream对象中的方法write,把读取到的文件上传到服务器
6.使用Socket中的方法get InputStream,获取网络字节输入流Inputstream对象
7.使用网络字节输入流InFutstream对象中的方法read读取服务回写的数据
8.释放资源(FiLeInputstream,Socket)
*/
package 网络通信;
import java.io.*;
import java.net.Socket;
public class 文件上传客户端 {
public static void main(String[] args) throws IOException {
//1.创建一个本地字节输入流FiLeInputstream对象,构造方法中绑定要读取的数据源
FileInputStream file = new FileInputStream("C:\\Users\\nj123\\Desktop\\1.png");
//2.创建一个客户端Socket对象,构造方法中绑定服务器的IP地址和端口号
Socket socket = new Socket("127.0.0.1", 8888);
//3.使用Socket中的方法getoutputstream,获取网络字节输出流OutputStream对象
OutputStream os = socket.getOutputStream();
//4.使用本地字节输入流FileInputstream的方法read,读取本地文件
int len=0;
byte bytes[]=new byte [1024];//创建一个字节数组
while((len=file.read(bytes))!=-1){
//5.使用网络字节输出流Outputstream对象中的方法write,把读取到的文件上传到服务器
os.write(bytes,0,len);
}
//结束标志,表示写入结束,上传成功。没有这一句程序会进入阻塞状态。
socket.shutdownOutput();
// 6.使用Socket中的方法get InputStream,获取网络字节输入流Inputstream对象
InputStream is = socket.getInputStream();
//7.使用网络字节输入流InFutstream对象中的方法read读取服务回写的数据
while((len=is.read(bytes))!=-1){
System.out.println(new String(bytes,0,len));
}
//8.释放资源(FiLeInputstream,Socket)
file.close();
socket.close();
}
}
---------------------------------------------------------
//服务器端
/*
文件上传案例服务器端:读取客户端上传的文件,保存到服务器的硬盘,给客户端回写“上传成功“
明确:
数据源:客户端上传的文件
目的地:服务器的硬盘 d:\\upload\\1.jpg
实现步骤:
1.创建一个服务器Serversocket对象,和系统要指定的端口号
2.使用Serversocket对象中的方法accept,获取到请求的客户端Socket对象
3.使用Socket对象中的方法get Inputstream,获取到网络字节输入流Input Stream对象
4.判断d:\\upload文件夹是否存在,不存在则创建
5.创建一个本地字节输出流FiLeoutputStream对象,构造方法中绑定要输出的目的地
6.使用网络字节输入流Inputstream对象中的方法read,读取客户端上传的文件
7.使用本地字节输出流FiLeoutputstream对象中的方法write,把读取到的文件保存到服务器的硬盘上
8.使用Socket对象中的方法getoutputstream,获取到网络字节输出流OutputStream对象
9.使用网络字节输出流Outputstream对象中的方法write,给客户端回写“上传成功“
10.释放资源(FiLeoutputstrea,Socket,ServerSocket)
*/
package 网络通信;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class 文件上传服务器端 {
public static void main(String[] args) throws IOException {
//1.创建一个服务器Serversocket对象,和系统要指定的端口号
ServerSocket server=new ServerSocket(8888);
//2.使用Serversocket对象中的方法accept,获取到请求的客户端Socket对象
Socket accept = server.accept();
//3.使用Socket对象中的方法get Inputstream,获取到网络字节输入流Input Stream对象
InputStream is= accept.getInputStream();
// 4.判断d:\\upload文件夹是否存在,不存在则创建
File f=new File("d:\\upload");
if(!f.exists()){
f.mkdir();
}
//5.创建一个本地字节输出流FiLeoutputStream对象,构造方法中绑定要输出的目的地
FileOutputStream file=new FileOutputStream("d:\\upload\\1.jpg");
//6.使用网络字节输入流Inputstream对象中的方法read,读取客户端上传的文件
int len=0;
byte bytes[]=new byte[1024];
while ((len=is.read(bytes))!=-1){
//7.使用本地字节输出流FiLeoutputstream对象中的方法write,把读取到的文件保存到服务器的硬盘上
file.write(bytes,0,len);
}
//8.使用Socket对象中的方法getoutputstream,获取到网络字节输出流OutputStream对象
OutputStream os = accept.getOutputStream();
//9.使用网络字节输出流Outputstream对象中的方法write,给客户端回写“上传成功“
os.write("上传成功".getBytes());
//10.释放资源(FiLeoutputstrea,Socket,ServerSocket)
file.close();
accept.close();
server.close();
}
}
//客户端不会输出上传成功,两边的程序进入了阻塞状态。在客户端读取文件上传到服务器端时,read方法出现堵塞
//解决办法:在文件上传完以后,我们自己给服务器写一个结束标志;在Socket对象中有一个方法:void shutdownOutput() 禁用此套接字的输出流。

参考资料:Java黑马视频

浙公网安备 33010602011771号