TCP通信:
TCP通信是面向连接的通信,客户端和服务器端必须三次握手,建立逻辑连接。
通信步骤:客户端请求服务器,建立连接,这个连接中包含一个IO(字节流)对象,用该对象进行通 信。服务器没有IO流,用客户端提供的IO流和客户端交互。
Java中,提供两个类用于实现TCP通信程序:
客户端: java.net.Socket 服务端:java.net.ServerSocket.
Socket:
构造方法:Socket(String host,int port) 创建一个流套接字并连接到指定主机的指定端口号
参数:String host:服务器名称/IP int port :端口号。
成员方法:OutputStream getOutputStream(), 返回此套接字的输出流。
InputStream getInputStream(),........................输入流。
实现步骤:1,创建Socket对象 。
2,用getOutputStream()获取网络字节输出流OutputStream对象。
3,用OutputStream对象的 write方法,给服务器发送数据。
4,用getInputStream() 获取 网络字节输入流InputStream对象。
5,用read方法,读取服务器返回的数据。
6,释放资源。
注意:1,客户端和服务器进行交互,必须使用Socket提供的网络流。
2,创建Socket对象的时候,就会和服务器三次握手建立连接,如果服务器没启动,会 抛出异常。
public static void main(String[] args) throws IOException{ Socket socket=new Socket("127.0.0.1",8888); OutputStream os= socket.getOutputStream(); os.write("hello server".getBytes()); InputStream is=socket.getInputStream(); byte[] bytes=new byte[1024]; int len=is.read(bytes); System.out.println(new String(bytes,0,len)); os.close(); }
ServerSocket:
构造方法: ServerSocket(int port) 创建绑定到特定端口的服务器套接字。
成员方法:Socket accept(),获取客户端的Socket对象。
public static void main(String[] args) throws IOException{ ServerSocket serverSocket=new ServerSocket(8888); Socket socket=serverSocket.accept(); InputStream is=socket.getInputStream(); byte[] bytes=new byte[1024]; int len=is.read(bytes); System.out.println(new String(bytes,0,len)); OutputStream os=socket.getOutputStream(); os.write("received".getBytes()); serverSocket.close(); socket.close(); }
文件上传案例:
总过程:客户端读取本地文件,上传到服务器,服务器把文件保存并反馈信息。
客户端代码:
public class Client { public static void main(String[] args) throws IOException{ File file=new File("C:\Users\天\Desktop\1.jpg"); FileInputStream fis=new FileInputStream(file); Socket socket=new Socket("127.0.0.1",8888); OutputStream os=socket.getOutputStream(); int len=0; byte[] bytes=new byte[1024]; while ((len=fis.read(bytes))!=-1){ os.write(bytes,0,len); } InputStream is = socket.getInputStream(); System.out.println(String.valueOf(is.read(bytes))); os.close(); fis.close(); socket.close(); } }
服务器代码:
public class Server { public static void main(String[] args) throws IOException{ File file=new File("C:\Users\天\Desktop\2.jpg"); ServerSocket serverSocket=new ServerSocket(8888); Socket socket=serverSocket.accept(); InputStream is = socket.getInputStream(); FileOutputStream fos=new FileOutputStream(file); 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(); serverSocket.close(); } }
出现问题:程序运行过程时,文件成功复制,但是程序并不会结束。
原因:客户端不会把结束标记写给服务器,服务器的read()读不到结束标记,会进入阻塞状态。
解决:给服务器写一个结束标记。
void shutdownOutput() : 禁用此套接字的输出流,后跟TCP的正常连接终止序列。