1.软件结构 C/S结构:客户端和服务器结构 B/S结构:浏览器和服务器结构 2.网络通信协议 应用层:HTTP,FTP,TFTP,SMTP,SNMP,DNS 传输层:TCP,UDP 网络层:ICMP,IGMP,IP,ARP,RARP 数据链路层:由底层网络定义的协议 3.网络编程三要素 协议 IP地址 查看本机IP地址: ipconfig 检查网络是否连通: ping IP地址 ping 220.181.57.216 端口号 用两个字节表示的整数,取值范围为0~65535 4.TCP通信程序 概述 两端通信时步骤: 1.服务端程序,需要事先启动,等待客户端连接 2.客户端主动连接服务器端,连接成功才能通信 客户端: java.nei.Socket类表示,创建Socket对象,向服务端发出连接请求,服务端响应请求,两者建立连接开始通信 服务端: java.net.ServerSocket类表示,创建ServerSocket对象,相当于开启一个服务,并等待客户端的连接 Socket类 该类实现客户端套接字,套接字指的是两台设备之间通讯的端点 套接字=IP地址+端口号 注意: 1.多个客户端同时和服务器进行交互,服务器必须明确和哪个客户端进行交互 在服务器端有一个方法accept客户端获取到请求的客户端对象 2.多个客户端同事和服务器进行交互,需要使用多个IO流对象 服务器是没有IO流的,服务器可以获取到请求的客户端对象Socket 使用每个客户端Socket中提供的IO流和客户端进行交互 服务器使用客户端的字节输入流读取客户端发送的数据 服务器使用客户端的字节输出流给客户端回写数据 总结:服务器使用客户端的流和客户端交互 客户端 构造方法 Socket(String host,int port):创建一个流套接字并将其连接到指定主机上的指定端口号 String host:服务器主机的名称/服务器IP地址 int port:副武器的端口号 成员方法 OutputStream getOutputStream():返回此套接字的输出流 InputStream getInputStream():返回此套接字的输入流
public class TCPClient { public static void main(String[] args) throws IOException { //创建一个客户端对象Socket,构造方法中绑定服务器的IP地址与端口号 Socket socket=new Socket("127.0.0.1",8888); //使用Socket对象中的方法getOutputStream()获取网络字节输出流对象 OutputStream os=socket.getOutputStream(); //使用OutputStream对象中的方法write给服务器发送数据 os.write("你好服务器".getBytes()); //使用Socket对象中的方法getInputStream()获取网络字节输入流InputStream对象 InputStream is=socket.getInputStream(); //使用网络字节输入流InputStream对象中的方法read,读取服务器回写的数据 byte[] bytes=new byte[1024]; int len=is.read(bytes); System.out.println(new String(bytes,0,len)); //释放资源 socket.close(); } }服务器端 构造方法 ServerSocket(int port):创建绑定到特定端口的服务器套接字 注意: 服务器必须知道是哪个客户端请求的服务器 可以使用accept方法获取到请求的客户端对象Socket 成员方法 Socket accept():侦听并接收到此套接字的连接
public class TCPServer { public static void main(String[] args) throws IOException { //创建服务器ServerSocket对象和系统要指定的端口号 ServerSocket server=new ServerSocket(8888); //使用ServerSocket对象中的方法accept,获取到请求的客户端对象Socket Socket socket=server.accept(); //使用Socket对象中的方法getInputStream()获取网络字节输入流InputStream对象 InputStream is=socket.getInputStream(); //使用网络字节输入流InputStream对象中的方法read,读取客户端发送的数据 byte[] bytes=new byte[1024]; int len=is.read(bytes); System.out.println(new String(bytes,0,len)); //使用Socket对象中的方法getOutputStream(),获取网络字节输出流OutputStream对象 OutputStream os=socket.getOutputStream(); //使用网络字节输出流OutputStream对象中的方法write,给客户端回写数据 os.write("收到谢谢".getBytes()); //释放资源 socket.close(); server.close(); } }上传文件案例 客户端
public class TCPClient { public static void main(String[] args) throws IOException { //创建一个本地字节输入流FileInputStream对象,构造方法中绑定要读取的数据源 FileInputStream fis=new FileInputStream("F:\\JAVA\\File\\picture.jpg"); //创建一个客户端Socket对象,构造方法中绑定服务器的IP地址和端口号 Socket socket=new Socket("127.0.0.1",8888); //使用Socket中的方法getOutputStream,获取网络字节输出流OutputStream对象 OutputStream os=socket.getOutputStream(); //使用本地字节输入流FileInputStream对象中的方法read读取本地文件 int len=0; byte[] bytes=new byte[1024]; while((len=fis.read(bytes))!=-1){ //使用网络字节输出流OutputStream对象中的方法write,把读取到的文件上传到服务器 os.write(bytes,0,len); } socket.shutdownOutput(); //使用Socket中的方法getInputStream,获取网络字节输出流OutputStream对象 InputStream is=socket.getInputStream(); while((len=is.read(bytes))!=-1){ //使用网络字节输入流InputStream对象中的方法read读取服务器回写的数据 System.out.println(new String(bytes,0,len)); } //释放资源 fis.close(); socket.close(); } }服务器端
public class TCPServer { public static void main(String[] args) throws IOException { //创建一个服务器ServerSocket对象,和系统要指定的端口号 ServerSocket server=new ServerSocket(8888); //使用ServerSocket对象中的方法accept,获取到请求的客户端Socket对象 Socket socket=server.accept(); //使用Socket对象中的getInputStream,获取到网络字节输入流InputStream对象 InputStream is = socket.getInputStream(); //判断文件夹是否存在,不存在则创建 File file=new File("F:\\JAVA\\File\\FileCopy"); if(!file.exists()){ file.mkdirs(); } //创建一个本地字节输出流对象FileOutputStream对象。构造方法中绑定要输出的目的地 FileOutputStream fos=new FileOutputStream("F:\\JAVA\\File\\FileCopy\\copy.jpg"); //使用网络字节输入流InputStream对象中的方法read,读取客户端上传的文件 int len=0; byte[] bytes=new byte[1024]; //使用本地字节输出流FileOutputStream对象中的方法write,把读取到的文件保存到服务器的硬盘上 while((len=is.read(bytes))!=-1){ fos.write(bytes,0,len); } //使用Socket对象中的方法getOutputStream,获取到网络字节输出流OutputStream对象 //使用网络字节输出流OutputStream对象中的方法write回写数据 socket.getOutputStream().write("上传成功".getBytes()); //释放资源 fos.close(); socket.close(); server.close(); } }模拟BS服务器
public class TCPServer { public static void main(String[] args) throws IOException { //创建一个服务器ServerSocket和系统要绑定的端口号 ServerSocket server=new ServerSocket(8080); //使用accept方法获取到请求的客户端对象 Socket socket = server.accept(); //使用Socket对象中的方法getInputStream。获取到网络字节输入流InputStream对象 InputStream is = socket.getInputStream(); //使用网络字节输入流InputStream对象中的方法read读取客户端的请求信息 //把网络字节输入流对象转换为字符输入流对象 BufferedReader br = new BufferedReader(new InputStreamReader(is)); //把客户端请求信息第一行读取出来 String line=br.readLine(); //把读取信息进行切割 String[] arr=line.split(" "); //进行截取 String htmlpath = arr[1].substring(1); //创建一个本地字节输入流,构造方法中读取htnl路径 FileInputStream fis=new FileInputStream(htmlpath); //使用Socket中的方法getOutputStream获取网络字节输出流OutputStream对象 OutputStream os=socket.getOutputStream(); os.write("HTTP/1.1 200 OK\r\n".getBytes()); os.write("Content-Type:text/html\r\n".getBytes()); os.write("\r\n".getBytes()); //一读一写,把服务器读取的html文件回写到客户端 int len=0; byte[] bytes=new byte[1024]; while((len=fis.read())!=-1){ os.write(bytes,0,len); } fis.close(); socket.close(); server.close(); } }