码迷,mamicode.com
首页 > Web开发 > 详细

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

时间:2015-09-20 17:50:49      阅读:211      评论:0      收藏:0      [点我收藏+]

标签:tcp   udp   socket   

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---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中填写要传输文件的绝对路径,也就是路径加文

    件名。


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



UDP

☆UDP聊天程序

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上传文本文件和图片文件)

标签:tcp   udp   socket   

原文地址:http://blog.csdn.net/u011479875/article/details/48597153

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!