TCP、UDP练习题 (UDP聊天程序、TCP上传文本文件和图片文件)

来源:互联网 发布:大数据的意义包括 多选 编辑:程序博客网 时间:2024/06/08 00:34

TCP、UDP编程练习


TCP

☆上传文本文件

读取一个本地文本文件,将数据发送到服务端,服务器端对数据进行存储。 存储完毕后,给客户端一个提示。

一、解题思路

客户端:(1) 创建Socket对象----用服务器的ip+端口号

(2)读取文件内容

(3)通过socket把内容发送给服务器端(把socket中的输出流包装成“打印流”来进行发送文本,是一种比较安全的输出方式,不会出现失真。)


服务器端:(1) 创建服务器socket---ServerSocket

    (2)通过ServerSocket获得客户端的socket

    (3)通过客户端的socket,读取对方发来的数据,并把这些数据写到一个新建文件当中


二、注解和实现代码

UploadTextClient.java类

package net.tcp.textFileUpload;import java.io.BufferedReader;import java.io.FileReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.Socket;import java.net.UnknownHostException;public class UploadTextClient {public static void main(String[] args) {try {//1 创建Socket对象----用服务器的ip+端口号Socket s = new Socket("127.0.0.1", 10000);//2 读取文件内容   //3 通过socket把内容发送给服务器端(把socket中的输出流包装成“打印流”来进行发送文本,是一种比较安全的输出方式,不会出现失真。)BufferedReader bufr = new BufferedReader( new FileReader("tempFile\\client.txt") );PrintWriter out = new PrintWriter(s.getOutputStream(), true);//发送String line = null;while((line=bufr.readLine())!=null){out.println(line);}//6 给服务器发送一个结束标记//out.println("%$#@88##K##");//发送自定义的结束标记s.shutdownOutput();//5 读取服务器端的反馈信息 s.getInputStream()BufferedReader bufr2 = new BufferedReader( new InputStreamReader(s.getInputStream()) );String text = bufr2.readLine();System.out.println("server:"+text);//4 关流bufr.close();out.close();s.close();} catch (UnknownHostException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}}

UploadTextServer.java类

package net.tcp.textFileUpload;import java.io.BufferedReader;import java.io.FileWriter;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.ServerSocket;import java.net.Socket;public class UploadTextServer {public static void main(String[] args) {try {//1 创建服务器socket---ServerSocketServerSocket server = new ServerSocket(10000);//2 通过ServerSocket获得客户端的socketSocket s = server.accept();//3 通过客户端的socket,读取对方发来的数据,并把这些数据写到一个新建文件当中//源:socket-->s.getInputStream()-->BufferedReader    目的:FileWriter("tempFile\\server.txt")--> 可以包装成PrintWriter来进行输出BufferedReader bufr = new BufferedReader(new InputStreamReader(s.getInputStream()));PrintWriter pw = new PrintWriter( new FileWriter("tempFile\\server.txt") ,true);String line = null;while((line=bufr.readLine())!=null){//if("%$#@88##K##".equals(line)){//break;//}pw.println(line);}//5 向客户端发送反馈信息,通过客户端的socket来发String str = s.getInetAddress().getHostName();str = str + "::: 文件上传成功...";PrintWriter out = new PrintWriter(s.getOutputStream(),true);out.println(str);//4 关流bufr.close();pw.close();s.close();server.close();} catch (IOException e) {e.printStackTrace();}}}



☆上传图片文件

客户端需求:把一个图片文件发送到服务端并读取回馈信息。要求判断文件是否存在及格式是否为jpg或gif并要求文件小于2M。

服务端需求:接收客户端发送过来的图片数据。进行存储后,回馈一个 上传成功字样。支持多用户的并发访问。

一、解题思路

客户端:(1)判断文件输出的文件是否存在:file.exists() && file.isFile()

      (2)判断文件的格式问题:file.getName().endsWith(".jpg")||file.getName().endsWith(".gif")

      (3)文件小于2M:file.length()>=1024*1024*2

      (4)然后通过IO读出文件的数据,并通过Socket将其发送给服务器端

注:在文件发送完后,记得给一个发送结束标志 s.shutdownOutput(),这句相当重要哦!!!


服务器端:主要就是解决多个客户端同时向服务器传送图片时,服务器端如何处理的问题。方法是通过new一个线程来解决。只要有客户端请求,就new一个线

程单独的与其交流,这要做的好处,满足了每个客户端同时和一个服务器进行多次交流。

二、注解和实现代码

UploadPicClient.java类

package net.tcp.picFileUpload;import java.io.File;import java.io.FileInputStream;import java.io.InputStream;import java.io.OutputStream;import java.net.Socket;public class UploadPicClient {public static void main(String[] args) throws Exception{//卫条件,反逻辑if(args.length!=1){System.out.println("请指定文件名");return;}File file = new File(args[0]);if( !(file.exists() && file.isFile()) ){System.out.println("上传的文件不存在");return;}if( !(file.getName().endsWith(".jpg")||file.getName().endsWith(".gif")) ){System.out.println("文件的扩展名必须是jpg或gif!");return;}if( file.length()>=1024*1024*2 ){System.out.println("文件过大,必须小于2M,请重新选择...");return;}Socket s = new Socket("127.0.0.1",10002);FileInputStream fis = new FileInputStream(file);OutputStream out = s.getOutputStream();byte buf[] = new byte[1024];int len=0;while((len=fis.read(buf))!=-1){out.write(buf, 0, len);}s.shutdownOutput();//发送结束标记//读取服务器的反馈信息InputStream in = s.getInputStream();byte b[] = new byte[1024];int len2 = in.read(b);String info = new String(b,0,len2);System.out.println(info);fis.close();out.close();s.close();}}
UploadPicServer.java类

package net.tcp.picFileUpload;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.ServerSocket;import java.net.Socket;public class UploadPicServer {public static void main(String[] args) throws Exception{ServerSocket server = new ServerSocket(10002);while(true){Socket s = server.accept();new Thread( new UploadThread(s) ).start();}}}class UploadThread implements Runnable{private Socket s = null;public UploadThread(Socket s) {this.s = s;}@Overridepublic void run() {String ip = s.getInetAddress().getHostAddress();System.out.println(ip+"....connected!");//接收来自客户端的数据(图片文件)File dir= new File("c:\\mypic");if(!dir.exists()){dir.mkdir();}int count =1;File file = new File(dir,ip+".jpg");while(file.exists()){  file = new File(dir,ip+"("+ (count++) +").jpg");}try {FileOutputStream fos = new FileOutputStream(file);byte buf[] = new byte[1024];int len=0;InputStream in = s.getInputStream();while((len=in.read(buf))!=-1){fos.write(buf, 0, len);}OutputStream out = s.getOutputStream();out.write((ip+"-->图片数据已经上传成功!").getBytes());//关流out.close();fos.close();s.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}}
注意一个小问题:就是在运行客户端程序(UploadPicClient.java)时,不能直接运行。

操作步骤:鼠标放在main方法上单击右键,选择Run As ---> Run Configurations --->Arguments --->Program arguments中填写要传输文件的绝对路径,也就是路径加文

    件名。


在客户端与服务器进行传输数据时,发送端和接收端的流一定要对应。



UDP

☆UDP聊天程序

a、通过键盘录入获取要发送的信息。

b、将发送和接收分别封装到两个线程中。

一、解题思路

因为是聊天程序,所以是两个客户端交流,所以只要写成一个客户端就可以,另一个只需要改一下发送端和接收端的端口。

每个客户端都有一个发送的DatagramSocket和一个接收的DatagramSocket;然后分别通过一个线程启动。这样保证在没有接到结束提示时,每个客户端都可以一直保持接收和发送的状态。

二、注解和实现代码

UDPChat.java类

package net.udp.updChat;//111111import java.net.DatagramSocket;import java.net.SocketException;public class UDPChat {public static void main(String[] args) {try {DatagramSocket send = new DatagramSocket(10003);//发送端口DatagramSocket receive = new DatagramSocket(10004);//接收端口new Thread( new Send(send) ).start();new Thread( new Receive(receive) ).start();} catch (SocketException e) {e.printStackTrace();}}}

Receive.java类

package net.udp.updChat;import java.io.IOException;import java.net.DatagramPacket;import java.net.DatagramSocket;public class Receive implements Runnable {DatagramSocket ds=null;public Receive(DatagramSocket ds) {this.ds = ds;}@Overridepublic void run() {try {byte buf[] = new byte[1024];while(true){DatagramPacket dp = new DatagramPacket(buf, buf.length);ds.receive(dp);String ip = dp.getAddress().getHostAddress();int port = dp.getPort();String str = new String( dp.getData(),0,dp.getLength() );System.out.println(ip+":"+port+"==> "+str);if("over".equalsIgnoreCase(str)){System.out.println(ip+"离开聊天室....");}}} catch (IOException e) {e.printStackTrace();}}}

Send.java类

package net.udp.updChat;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetAddress;public class Send implements Runnable {DatagramSocket ds=null;public Send(DatagramSocket ds) {this.ds = ds;}@Overridepublic void run() {try {BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));String line=null ;while((line= bufr.readLine())!=null){byte buf[] = line.getBytes();DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName("192.168.31.115"),10002);//(10002)与另一个客户端的接收端口相同ds.send(dp);if("over".equalsIgnoreCase(line)){break;}}ds.close();} catch (IOException e) {e.printStackTrace();}}}









0 0