TCP、UDP编程练习
读取一个本地文本文件,将数据发送到服务端,服务器端对数据进行存储。 存储完毕后,给客户端一个提示。
客户端:(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---ServerSocket ServerSocket server = new ServerSocket(10000); //2 通过ServerSocket获得客户端的socket Socket 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; } @Override public 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中填写要传输文件的绝对路径,也就是路径加文
件名。
在客户端与服务器进行传输数据时,发送端和接收端的流一定要对应。
a、通过键盘录入获取要发送的信息。
b、将发送和接收分别封装到两个线程中。
因为是聊天程序,所以是两个客户端交流,所以只要写成一个客户端就可以,另一个只需要改一下发送端和接收端的端口。
每个客户端都有一个发送的DatagramSocket和一个接收的DatagramSocket;然后分别通过一个线程启动。这样保证在没有接到结束提示时,每个客户端都可以一直保持接收和发送的状态。
UDPChat.java类
package net.udp.updChat; //111111 import 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; } @Override public 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; } @Override public 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(); } } }
版权声明:本文为博主原创文章,未经博主允许不得转载。
TCP、UDP练习题 (UDP聊天程序、TCP上传文本文件和图片文件)
原文地址:http://blog.csdn.net/u011479875/article/details/48597153