1.2.应用案例4671-672-673
1.编写服务端和客户端
2.8888端口监控服务器端口
3.客户端连接到服务端,发送图片e:\\guidao.jpg
4.服务器端接收客户端发送的图片,保存在src下,发送“接收图片”并退出
5.客户端收到服务端发送的“收到图片”,然后退出
6.该程序要求使用Streamutilss.java,我们直接使用它
com中的代码.stulzl.socket_04.TCPFileuploadserverver
package com.stulzl.socket_04;import java.io.*;import java.net.ServerSocket;import java.net.Socket;//文件上传服务端 672-673/1.编写服务端,在8888端口与客户端//2.服务器端监控//3.客户端连接到服务端,发送图片e:\guidao2.jpg//4.服务器端接收客户端发送的图片,保存在src下,发送“接收图片”,然后退出//5。客户端接收服务端发送的“接收图片”。然后退出//6.这个程序需要Streamutilss.java,我们直接使用publicic class TCPFileUploadServer { public static void main(String[] args) throws Exception { ///服务端监控888端口 ServerSocket serverSocket = new ServerSocket(8888); System.out.println(服务端在888端口监控…); //等待连接 Socket socket = serverSocket.accept(); //3. 阅读客户端发送的数据 // 通过Socket获得输入流 BufferedInputStream bis = new BufferedInputStream(socket.getInputStream()); ///使用工具类获取客户端发送的数组数据信息 byte[] bytes = StreamUtils.streamToByteArray(bis); //4. 将得到 bytes 数组,写入指定路径,拿到一份文件 String destFilePath = "src\guidao2.jpg"; BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFilePath)); bos.write(bytes); ///回复客户端收到图片 ///通过Socket获得输出流(使用字符流) BufferedWriter bfw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); bfw.write(收到图片); bfw.flush();///将数据刷新到数据通道 socket.shutdownOutput();//结束标记 //关闭 bfw.close(); bos.close(); bis.close(); serverSocket.close(); socket.close(); }}
TCPFileUploadClient客户端
package com.stulzl.socket_04;import java.io.*;import java.net.InetAddress;import java.net.Socket;////文件上传的客户端 672-673ublic class TCPFileUploadClient { public static void main(String[] args) throws Exception { //客户端连接服务端8888,到Socket对象 Socket socket = new Socket(InetAddress.getLocalHost(),8888); ///创建读取磁盘文件的输入流 String filePath = "e:\\guidao.jpg"; BufferedInputStream bis = new BufferedInputStream(new FileInputStream(filePath)); ///使用提供的工具 ///将图片数据放入bytes数组 byte[] bytes = StreamUtils.streamToByteArray(bis); ///通过socket获得输出流, 将bytes数据发送到服务端 ///将outputstream输出转换为bufferedoutstream,目的是为了方便 BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream()); bos.write(bytes);//将文件对应的字节数据数组内容,写入数据通道 bis.close();//关闭 socket.shutdownOutput();//设置结束标记 ///从服务端接收回复的消息 InputStream inputStream = socket.getInputStream(); //使用工具Streamutils 的方法,直接将 inputStream 读取的内容 转成字符串 String s = StreamUtils.streamToString(inputStream); System.out.println(s);//输出 bos.close(); socket.close(); }}
Streamutils工具
package com.stulzl.socket_04;import java.io.BufferedReader;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;/** * 这种读写方法用于演示流动的读写方法 * */public class StreamUtils {/** * 功能:将输入流转换为byte[], 您可以在byte[]中读取文件的内容 * @param is * @return * @throws Exception */public static byte[] streamToByteArray(InputStream is) throws Exception{ByteArrayOutputStream bos = new ByteArrayOutputStream();///创建输出流对象byte[] b = new byte[1024];//字节数组int len;while((len=is.read(b))!=-1){///循环读取boss.write(b, 0, len);//把读取的数据,写入bos}byte[] array = bos.toByteArray();//然后bos 转换成字节数组bos.close();return array;}/** * 功能:将InputStream转换为String * @param is * @return * @throws Exception */public static String streamToString(InputStream is) throws Exception{BufferedReader reader = new BufferedReader(new InputStreamReader(is));StringBuilder builder= new StringBuilder();String line;while((line=reader.readLine())!=null){//当读到孔时,就意味着结束builder.append(line+"\r\n");}return builder.toString();}}
3.netstat指令6744
1.netstat-an可以查看当前主机的网络情况,包括端口监控和网络连接
2.netstat-an|more可以在分页上显示
3.要求在dos控制台下执行快捷键win+r
说明:
(1)Listening表示某个端口在监控
(2)如果有外部程序(客户端)连接到端口,则显示连接信息
(3)可输入ctrl+c退出指令
4.未知的TCP网络通信秘密6751.当客户端连接到服务端时,客户端实际上是通过端口和服务端通信的。该端口由TCP/IP分配,不确定且随机.(这句话的意思是,在客户端和服务端通信时,服务端不仅会有端口,还会在客户端生成通信的端口)
5.UDP网络通信编程[理解]6765.1基本介绍6761.类DatagramSocket和DatagramPacket基于UDP协议的网络程序实现了[数据包/数据报]。
2.UDP数据报告通过DatagramSocket发送和接收数据报套接字,系统不能保证UDP数据报告能够安全发送到目的地,也不能确定何时到达。
3.DatagramPacket对象包含UDP数据报,包括发送端IP地址和端口号,以及接收端IP地址和端口号。
4.UDP协议中的每个数据报告都提供了完整的地址信息,因此无需建立发送方和接收方之间的连接
5.2基本流程6761.DatagramSocket和DatagramPacket两个核心类别/对象
2.建立接收端(没有服务端和客户端的概念)
3.在发送数据之前,建立数据包/报告DatagramPacket对象
4.调用DatagramSocket的发送和接收方法
5.关闭DatagramSocketet
5.3应用案例1.编写接收端A和发送端B
2.接收端A在999端口等待接收数据(receive)
3.发送端B向接收端A发送数据hello,明天吃火锅~”
4.接收端A接收发送端B发送的数据,回复“好的,明天见”,然后退出
5.发送端接收回复数据,然后退出
com中的代码.stulzl.udp_.包中发送端UDPSenderber
package com.stulzl.udp_;import java.io.IOException;import java.net.*;//发送端 677-678/1.编写接收端A,接收端A在999端口等待接收数据(receive)/3.发送端B向接收端A发送数据hello,明天吃火锅~”//4.接收端A收到发送端B发送的数据,回复“好的,明天见”,然后退出//5。发送端接收回复的数据,退出public class UDPSenderB { public static void main(String[] args) throws IOException { ///创建DatagramSocket对象,准备发送和接收9998端口的数据 DatagramSocket socket = new DatagramSocket(9998); //将需要发送的数据,在DatagramPacket对象中包装 byte[] data = "hello 明天吃火锅“明天吃火锅”.getBytes();//getBytes()将字符串转成字节数组 //解释为什么不使用InetAdress.getLocalHost()找主机地址,因为InetAdress,.getLocalHost() //主要是给自己的电脑发,但一般来说,我们向其他主机发送数据,所以 // 使用InetAdress使用Inetadress.getByName("192.168.1.8")方法 192.168.1.8主机ip ////这里调用的是发送结构器 DatagramPacket packet = new DatagramPacket(data, data.length,InetAddress.getByName("192.168.1.8") , 9999); //发送 socket.send(packet); ////接收A发送的数据 byte[] br = new byte[1024];///缓冲数组 DatagramPacket packet1 = new DatagramPacket(br, br.length);////这里调用的是接收构造器 socket.receive(packet1);//接收 ////拆包接收到的数据 int length = packet1.getLength();////实际接收的数据长度 byte[] data2 = packet1.getData();///取出数据 String s = new String(data2,0,length);///字节数组编程字符串 System.out.println(s);//输出 //关闭 socket.close(); System.out.println(B端退出…; }}
接收端UDPReceiver
package com.stulzl.udp_;import javax.swing.*;import java.io.IOException;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetAddress;import java.net.SocketException;//接收端 677-678ublic class UDPReceiverA { public static void main(String[] args) throws IOException { ///创建DatagramSocket对象,准备在999端口接收数据 DatagramSocket socket = new DatagramSocket(9999); //构建DatagramPacket对象,准备接收数据,UDP协议数据包最大64k byte[] buf = new byte[1024];///缓冲数组 DatagramPacket packet = new DatagramPacket(buf,buf.length);////这里调用的是接收构造器 ///调用接收方法,通过网络传输的DatagramPacket对象填充到packet对象 //提示: 当发送到数据包时 本机的 9999 端口时,数据将被接收 //如果没有数据包发送到 本机的 9999 端口, 会阻止等待 System.out.println("接收端 A 等待接收数据.."); socket.receive(packet); //可以拆包packet,取出数据并显示 int length = packet.getLength();////实际接收到的数据字节长度 byte[] data = packet.getData();///取出数据 String s = new String(data,0,length);///字节数组编程字符串 System.out.println(s);//输出 好的,明天见“//送B” byte[] brr ="好的,明天见".getBytes(); ////这里调用的是发送结构器 DatagramPacket packet1 = new DatagramPacket(brr, brr.length, InetAddress.getByName("192.168.1.8"), 9998); socket.send(packet1);///发送数据 //关闭 socket.close(); System.out.println(A端退出…; }}
6.练习1679
(1)使用字符流编写客户端程序和服务器端程序,
(2)客户端发送”name服务器端接收后,返回“我是nova”,nova是你自己的名字.
(3)客户端发送”hobby编写java程序,服务器端接收后返回
(4)不是这两个问题,回复“你说什么?”
com中的代码.stulzl.exercise01.包中服务端Exercise01server
package com.stulzl.exercise01;import java.io.*;import java.net.ServerSocket;import java.net.Socket;//服务端 679//(1) 使用字符流, 编写客户端程序和服务器端程序,//(2) 客户端发送“客户端发送”name服务器端接收后,返回“我是nova” ",nova是你自己的名字.//(3) 客户端发送 "hobby编写java程序/(4),服务器端接收后返回 不是这两个问题,回复“你说什么?”public class Exercisese01servererer { public static void main(String[] args) throws IOException { ////找到9999端口 ServerSocket serverSocket = new ServerSocket(9999); System.out.println(9999端口监听,等待连接…”; //等待连接 Socket socket = serverSocket.accept(); //IO读取客户端发送的信息,读取客户端写入数据通道的数据 InputStream inputStream = socket.getInputStream(); ///用字符流读取 Inputstreamreader转换流将字节转换为字符 BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); String s = bufferedReader.readLine();///读取数据 String answer =""; if("name".equals(s)){ answer = “我是nova”; }else if("hobby".equals(s)){ answer = “编写java程序”; }else{ answer = “你在说什么?”; } OutputStream outputStream = socket.getOutputStream(); ////使用字符流恢复信息 BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream)); bufferedWriter.write(answer); bufferedWriter.newLine();///插入一个换行符表示写入内容结束 bufferedWriter.flush();//刷新 System.out.println(服务端退出…; //关闭 serverSocket.close(); socket.close(); bufferedReader.close(); bufferedWriter.close(); }}
Exercise01Client客户端
package com.stulzl.exercise01;import java.io.*;import java.net.InetAddress;import java.net.Socket;import java.util.Scanner;//客户端 679public class ClientExercise01 { public static void main(String[] args) throws IOException { ///连接9999端口 Socket socket = new Socket(InetAddress.getLocalHost(), 9999); OutputStream outputStream = socket.getOutputStream(); //通过输出流,写入数据到 数据通道 使用字符流 OutputstreamWriter字节流转换为字符流 BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream)); ////从键盘或用户的问题 Scanner scanner = new Scanner(System.in); System.out.println(“请输入您的问题”); String question = scanner.next(); bufferedWriter.write(question); bufferedWriter.newLine();///插入换行符表示写入内容结束。使用newline()也要求对方使用readline()阅读 bufferedWriter.flush();///使用字符流必须手动刷新,否则,数据将不会被写入数据通道 ////接收服务端的返回信息 InputStream inputStream = socket.getInputStream(); ///使用字符流读取数据 BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); String s = bufferedReader.readLine(); System.out.println(s); System.out.println(关闭客户端…; //关闭 socket.close(); bufferedReader.close(); bufferedWriter.close(); }}
7.练习2680
(1)用UDP协议编写接收端A和发送端B
(2)接收端在888端口等待接收数据(receive)
(3)发送端向接收端发送数据“四大名称是什么”
(4)接收端接收到发送端发送的问题后,返回“四大名称”<<红楼梦>>..否则,返回what,否则将返回what
(5)退出接收端和发送端程序
com中的代码.stulzl.exercise02.Exercise02senderber
package com.stulzl.exercise02;import java.io.IOException;import java.net.*;import java.util.Scanner;//发送端 680public class Exercise02senderber { public static void main(String[] args) throws IOException { ///创建DatagramSocket对象,在8889端口发送 DatagramSocket socket = new DatagramSocket(8889); Scanner scanner = new Scanner(System.in); System.out.println("请输入问题:"; String question = scanner.next(); byte[] buf =question.getBytes();//转成字节数组 ///调用发送数据构造器 DatagramPacket packet = new DatagramPacket(buf, buf.length, InetAddress.getByName("192.168.1.8"), 8888); socket.send(packet);//发送 //接收返回信息 //调用接收结构器 byte[] banswer = new byte[1024];//缓冲 DatagramPacket packet2 = new DatagramPacket(banswer, banswer.length); socket.receive(packet2);//接收数据 ////拆包接收到的数据 int length = packet2.getLength();////实际获得的数据长度 byte[] data = packet2.getData();//实际获得的数据 String s = new String(data, 0, length);///转成字符串 System.out.println(s);//输出 //关闭 socket.close(); System.out.println(“发送端退出…”; }}
Exercise02Receiveraeraer接收端
package com.stulzl.exercise02;import java.io.IOException;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetAddress;import java.net.SocketException;//接收端 680//(1)写一个接收端A,和一个发送端B, 用UDP协议完成//(2)在888端口等待接收数据(receive)//(3)发送端向接收端发送数据“四大名称是什么”//(4)接收端接收发送端发送的问题后,返回“四大名称是什么”<<红楼梦>> ..否则,返回what,否则将返回what//(5)接收端和发送端程序退出public) class Exercise02Receiver { public static void main(String[] args) throws IOException { ///创建DatagramSocket对象,在8888端口接收 DatagramSocket socket = new DatagramSocket(8888); byte[] buf = new byte[1024];///缓冲数组 //调用接收结构器 DatagramPacket packet = new DatagramPacket(buf, buf.length); socket.receive(packet);//接收数据 ////拆包接收到的数据 int length = packet.getLength();////实际获得的数据长度 byte[] data = packet.getData();//实际获得的数据 String s = new String(data, 0, length);///转成字符串 String answer = ""; if(四大名字是什么?.equals(s)){ answer = “四大名字是:三国演义,西游记,水浒传,红楼梦"; }else{ answer = "what?"; } ///发送数据答案 byte[] bAnswer = answer.getBytes();///将字符串转成字节数组 ///调用发送数据的构造器 DatagramPacket packet1 = new DatagramPacket(bAnswer, bAnswer.length, InetAddress.getByName("192.168.1.8"), 8889); socket.send(packet1); //关闭 socket.close(); System.out.println("接收端退出.."; }}
8.练习3681-682
(1)编写客户端程序和服务器端程序
(2)客户端可以输入音乐文件名称,如山川。服务器收到音乐名称后,可以将音乐文件返回客户端。如果服务器没有此文件,则可以返回默认音乐.
(3)客户端收到文件后,保存到本地e:\\
(4)提示:Streamutilss可用于此程序.java
com中的代码.stulzl.exercise03.包Exercise03Server
package com.stulzl.exercise03;import java.io.*;import java.net.ServerSocket;import java.net.Socket;//服务端 编写客户端程序和服务器端程序//(2)客户端可以输入音乐文件名,681-682/(1)比如高山流水,服务端收到音乐名后,/// 如果服务器没有这个文件,您可以返回客户端的音乐文件并返回默认音乐.//(3)客户端收到文件后,保存到本地e:\/(4)提示:这个程序可以使用Streamutilss.javapublic class Exercise03Server { public static void main(String[] args) throws Exception { ///监听9999端口 ServerSocket serverSocket = new ServerSocket(9999); System.out.println(服务端在999端口监听,等待下载文件…”; //等待连接 Socket socket = serverSocket.accept(); ///阅读客户端发送的文件名 InputStream inputStream = socket.getInputStream(); byte[] b = new byte[1024];//缓冲字节数组 int readLen = 0; String downLoadFile = "";//保存文件名 //循环读取 while((readLen = inputStream.read(b))!=-1){ downLoadFile += new String(b,0,readLen);//+=是为了防止文件名过长,起到拼接文件名的作用 } System.out.println(“客户希望下载的文件名=”+downLoadFile); 服务器上有两个文件, 无名.mp3 高山流水.mp3 ///如果客户下载 高山流水 我们将返回文件,否则全部返回 无名.mp3 String resFileName = ""; if(“高山流水”.equals(downLoadFile)){ resFileName = "src\高山流水.mp3"; }else{ resFileName = "src\\无名.mp3"; } //创建输入流,读取文件 BufferedInputStream bis = new BufferedInputStream(new FileInputStream(resFileName)); //使用工具,读取文件到字节数组 byte[] bytes = StreamUtils.streamToByteArray(bis); ////与Socket相关的输出流 BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream()); //将数据写入数据通道,返回给客户端 bos.write(bytes); socket.shutdownOutput();//结束标记 //关闭流 bis.close(); bos.close(); inputStream.close(); socket.close(); serverSocket.close(); System.out.println(服务端退出…; }}
Exercise03Client客户端
package com.stulzl.exercise03;import java.io.*;import java.net.InetAddress;import java.net.Socket;import java.net.UnknownHostException;import java.time.chrono.IsoChronology;import java.util.Scanner;///文件下载的客户端 681-682 class Exercise03Client { public static void main(String[] args) throws Exception { //接收用户输入,指定下载文件名 Scanner scanner = new Scanner(System.in); System.out.println("请输入要下载的文件:"); String downloadFileName = scanner.next(); ///准备发送连接服务端口 Socket socket = new Socket(InetAddress.getLocalHost(), 9999); ///创建与socket相关的输出流 OutputStream outputStream = socket.getOutputStream(); outputStream.write(downloadFileName.getBytes());///转换为字节数组发送 //设置结束标记 socket.shutdownOutput(); ///阅读服务器返回的文件(字节数组) BufferedInputStream bis = new BufferedInputStream(socket.getInputStream()); byte[] bytes = StreamUtils.streamToByteArray(bis); //创建输出流,将bytes写入磁盘 String filePath = "e:\\"+downloadFileName+".mp3"; BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath)); bos.write(bytes); //关闭 bos.close(); bis.close(); outputStream.close(); socket.close(); System.out.println(客户端下载完毕,退出……”; }}
Streamutils工具
package com.stulzl.exercise03;import java.io.BufferedReader;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;/** * 这种读写方法用于演示流动的读写方法 * */public class StreamUtils {/** * 功能:将输入流转换为byte[], 您可以在byte[]中读取文件的内容 * @param is * @return * @throws Exception */public static byte[] streamToByteArray(InputStream is) throws Exception{ByteArrayOutputStream bos = new ByteArrayOutputStream();///创建输出流对象byte[] b = new byte[1024];//字节数组int len;while((len=is.read(b))!=-1){///循环读取boss.write(b, 0, len);//把读取的数据,写入bos}byte[] array = bos.toByteArray();//然后bos 转换成字节数组bos.close();return array;}/** * 功能:将InputStream转换为String * @param is * @return * @throws Exception */public static String streamToString(InputStream is) throws Exception{BufferedReader reader = new BufferedReader(new InputStreamReader(is));StringBuilder builder= new StringBuilder();String line;while((line=reader.readLine())!=null){builder.append(line+"\r\n");}return builder.toString();}}