通信两端严格区分客户端和服务器端
* 通讯步骤:
* 1,服务端程序事先启动,等待客户端连接;
* 2,客户端主动连接服务器端,建立逻辑连接,连接成功可以通信,服务器不主动连接客户端。
* Java中用于TCP通信程序的类:
* 1,客户端:java.net.Socket类,创建Socket对象,发出连接请求;
* 2,服务器端:java.net.ServerSocket类,创建ServerSocket对象,等待连接。
* 多个客户端同时与服务器进行交互,服务器端利用accept方法收到请求的客户端对象;
* 客户端与服务器进行一个数据交互需要4个IO流对象。
* 客户端:
* 套接字:包含IP地址和端口号的网络单位;
* * Socket(String host,int part)
* * 参数:host:IP地址;part:端口号;
* * 成员方法:
* * OutputStream getOutputStream()返回套接字的输出流
* * InputStream getInputStream()返回套接字的输入流
* * void close()关闭套接字
* * 实现步骤:
* * 1,创建一个客户端对象Socket,构造方法绑定IP地址和端口号;
* * 2,使用Socket对象中的getOutputStream()获取网络字节输出流对象;
* * 3,使用OutputStream对象中的方法write,给服务器发送数据;
* * 4,使用Socket对象中的方法getInputStream()获取网络字节输入流对象;
* * 5,使用InputStream对象中方法read,读取服务器中回写的数据
* * 6,释放资源,关闭Socket;
* 注意事项:
* 1,客户端与服务器进行交互,必须使用Socket中的提供的网络流,不能使用自己创建的流对象;
* 2,创建Socket对象,回去请求服务器并经过三次握手建立连接,若服务器未启动则抛出异常。
public class SClient {
public static void main(String[] args) throws IOException {
Socket socket=new Socket("127.0.0.1",8888);
OutputStream os=socket.getOutputStream();
os.write("客户端向服务器端发送请求".getBytes());
InputStream is=socket.getInputStream();
byte[] bytes=new byte[1024];
int len=is.read(bytes);
System.out.println(new String(bytes));
socket.close();
}
}
* 服务器端:接收请求,读取数据,回写数据;
* 构造方法:
* ServerSocket(int port)绑定指定端口的服务器套接字
* 成员方法:
* Socket accept()侦听并接收指定端口号
* 服务器的实现步骤:
* 1,创建服务器对象,和系统请求指定的端口号;
* 2,使用accept方法,获取请求的客户端对象
* 3,使用getInputStream获取网络字节输入流InputStream对象
* 4,使用read方法读取发送的数据;
* 5,使用getOutputStream获取网络字节输出流对象
* 6,使用write方法回写数据
* 7,释放资源,关闭Socket, ServerSocket
public class SServer {
public static void main(String[] args) throws IOException {
ServerSocket server=new ServerSocket(8888);
Socket socket=server.accept();
InputStream is=socket.getInputStream();
byte[] bytes=new byte[1024];
int len=is.read(bytes);
System.out.println(new String(bytes));
OutputStream os=socket.getOutputStream();
os.write("服务器端已收到客户端请求".getBytes());
socket.close();
server.close();
}
}
Prac
* 文件上传案例:
* 客户端读取本地文件,把文件上传到服务器,服务器把上传的文件保存到服务器的硬盘上;
* 步骤:
* 1,客户端使用本地字节输入流读取上传文件。
* 2,客户端使用网络字节输出流,将读取文件上传到服务器。
* 3,服务器使用网络字节输入流,读取客户端上传的文件。
* 4,服务器使用本地字节输出流,把读取到文件保存到服务器硬盘。
* 5,服务器使用网络字节输出流,给客户端回写提示信息。
* 6,客户端使用网络字节输入流,读取服务器回写数据。
* 7,释放资源。
* 注意事项:
* 1,客户端与服务器与本地硬盘读写,需要使用本地流;
* 2,客户端与服务器之间进行读写,必须使用Socket中的网络流;
* 3,文件上传需明确数据源于数据目的地。
实现
客户端
* 读取本地文件,上传到服务器,读取服务器回写的数据。
* 步骤:
* 1,创建一个本地字节输入流,绑定读取的数据源
* 2,创建客户端Socket对象,绑定ip地址与端口号
* 3,使用getOutputStream获取网络字节输出流
* 4,使用本地输入流read读取本地文件
* 5,使用网络字节输出流write将读取文件上传到服务器
* 6,使用Scoket中方法获取网络字节输入流
* 7,使用网络字节输入流read读取服务器回写的数据
* 8,释放资源
public class TCPPracClient {
public static void main(String[] args) throws IOException {
FileInputStream fis=new FileInputStream("src\\Internet\\upload.txt");
Socket socket=new Socket("127.0.0.1",8890);
OutputStream os=socket.getOutputStream();
int len=0;
byte[] bytes=new byte[1024];
while((len=fis.read(bytes))!=-1){
os.write(bytes,0,len);
}
socket.shutdownOutput();
InputStream is=socket.getInputStream();
while((len=is.read(bytes))!=-1){
System.out.println(new String(bytes,0,len));
}
fis.close();
socket.close();
}
}
服务器端
* 读取客户端读取的数据,保存到服务器的硬盘上,回写上传成功
* 实现步骤:
* 1,创建服务器对象,指定端口
* 2,使用ServerSocket中accept方法接受客户端请求的Socket对象
* 3,使用getInputStream获取字节输入流对象
* 4,创建本地字节输出流对象,方法中绑定目的地
* 5,使用网络字节输入流读取文件
* 6,使用write将读取对象保存
* 7,使用getOutputStream中方法获取对象,并对该对象回写信息
* 8,释放资源
public class TCPPracSever {
public static void main(String[] args) throws IOException {
ServerSocket server=new ServerSocket(8890);
Socket socket=server.accept();
InputStream is=socket.getInputStream();
FileOutputStream fos=new FileOutputStream("src\\Internet\\save.txt");
int len=0;
byte[] bytes=new byte[1024];
while((len=is.read(bytes))!=-1){
fos.write(bytes,0,len);
}
socket.getOutputStream().write("文件上传成功".getBytes());
fos.close();
socket.close();
server.close();
}
}