『Java』网络编程--TcpExercise

✔TCP复制文件

 

import java.io.*;

import java.net.*;

class Client{

public static void main(String[] args)throws Exception{

//建立Socket服务

Socket client=new Socket("127.0.0.1",10000);

//读取本地文件到缓存

BufferedReader bur=

new BufferedReader(new FileReader("TcpExercise.java"));

 

//将缓存中的数据打印到服务端.

PrintStream ps=new PrintStream(client.getOutputStream(),true);

//定义一个结束标记.

String flg="*^*&(";

//发到服务端,告诉他标记

ps.println(flg);

 

String line=null;

while((line=bur.readLine())!=null){

ps.println(line);

}

ps.println(flg);

 

//读取服务端反馈的信息

BufferedReader uploadinfo=

new BufferedReader(new InputStreamReader(client.getInputStream()));

System.out.println(uploadinfo.readLine());

 

bur.close();

client.close();

}

}

class Server{

public static void main(String[] args)throws Exception{

//建立ServerSocket服务

ServerSocket server=new ServerSocket(10000);

Socket client=server.accept();

 

 

//当然,这里其实应该,将文件名先传进来,让后,根据文件名判断建立新文件

//这里,重点不是这里,所以,就把改程序文件写成固定的

PrintWriter out=new PrintWriter(new FileWriter("Server.java"),true);

 

//循环读入客户端信息,并写入文件

BufferedReader br=new BufferedReader(new InputStreamReader(client.getInputStream()));

 

//接受标记,并存储

String flg=br.readLine();

 

String line=null;

while((line=br.readLine())!=null){

if(line.equals(flg))

break;

 

out.println(line);

}

PrintStream ps=new PrintStream(client.getOutputStream(),true);

ps.println("上传成功....");

 

out.close();

client.close();

}

}

 

以上主要注意的是,标记问题.因为,无论是客户端还是服务端都,有阻塞式方法.这也是TCP中的常见问题

 

 void

shutdownInput() 
          此套接字的输入流置于“流的末尾”。

 

 void

shutdownOutput() 
          禁用此套接字的输出流。

 

 

✔用时间戳来搞定标记

 

 

import java.io.*;
import java.net.*;
class Client{
	public static void main(String[] args)throws Exception{
		//建立Socket服务
		Socket client=new Socket("127.0.0.1",10000);
		//读取本地文件到缓存
		BufferedReader bur=
				new BufferedReader(new FileReader("TcpExercise.java"));

	  
	
	  
	  //自定义时间差标记
	   long time=System.currentTimeMillis();
	
			DataOutputStream dos=new DataOutputStream(client.getOutputStream());
			dos.writeLong(time);
		
		
		
		//将缓存中的数据打印到服务端.
		PrintStream ps=new PrintStream(client.getOutputStream(),true);

		String line=null;
	
		while((line=bur.readLine())!=null){
			ps.println(line);
		}

		
		dos.writeLong(time);
	
		
		
		//读取服务端反馈的信息
		BufferedReader uploadinfo=
				new BufferedReader(new InputStreamReader(client.getInputStream()));
		System.out.println(uploadinfo.readLine());
		
		bur.close();
		client.close();
		
		
	}
}
class Server{
	public static void main(String[] args)throws Exception{
	//建立ServerSocket服务
	ServerSocket server=new ServerSocket(10000);
	Socket client=server.accept();
	
	
	//时间标记
	DataInputStream dis=new DataInputStream(client.getInputStream());
	long time=dis.readLong();
	System.out.println(time);

	
	
	
	//当然,这里其实应该,将文件名先传进来,让后,根据文件名判断建立新文件
	//这里,重点不是这里,所以,就把改程序文件写成固定的
	PrintWriter out=new PrintWriter(new FileWriter("Server.java"),true);
	
	
	//循环读入客户端信息,并写入文件
	BufferedReader br=new BufferedReader(new InputStreamReader(client.getInputStream()));


		
	String line=null;
	long ti=0;
	while((line=br.readLine())!=null){
	if((ti=dis.readLong())==time)
		System.out.println("he");
		
		System.out.println(ti);
		out.println(line);
		System.out.println(line);
	
	//反馈客户度

}
	PrintStream ps=new PrintStream(client.getOutputStream(),true);
	ps.println("上传成功....");
	
	
	out.close();
	client.close();
}
}

 

 

 

 

 

Tcp上传图片

 

import java.io.*;

 

import java.net.*;

/*客户端

1,服务端点

2,读取客户端已有的图片数据

3,通过socket,输出流将数据发给服务端

4,读取服务端反馈信息

5,关闭

*/

class Client{

public static void main(String[] args)throws Exception{

Socket client=new Socket("127.0.0.1",10000);

//File读取数据

FileInputStream fis=new FileInputStream("client.png");

//获取网络out流将图片写进去

OutputStream os=client.getOutputStream();

//开工

byte[] buf=new byte[1024];

int len=0;

while((len=fis.read(buf))!=-1){

os.write(buf,0,len);

}

//结束标记

client.shutdownOutput();

 

//读取,反馈

InputStream is=client.getInputStream();

byte[] by=new byte[1024];

int lenn=is.read(by);

System.out.println(new String(by,0,lenn));

 

fis.close();

client.close();

 

}

}

class Server{

public static void main(String[] args)throws Exception{

ServerSocket server=new ServerSocket(10000);

Socket client=server.accept();

//创建文件等待接受

FileOutputStream fos=new FileOutputStream("server.png");

//活的input

InputStream is=client.getInputStream();

byte[] buf=new byte[1024];

int len=0;

while((len=is.read(buf))!=-1){

fos.write(buf,0,len);

}

 

//获取out反馈

OutputStream os=client.getOutputStream();

os.write("成功上传".getBytes());

 

fos.close();

client.close();

 

 

}

}

用多线实现,多台客户端想服务端发送图片.

服务端:

 

 

 

 

 ✔TCP协议多线程接受N个客户端发来的图片

import java.io.*;
import java.net.*;
class PicClient{
	public static void main(String[] args)throws Exception{
		if(args.length!=1)
		{
			System.out.println("请选择一个jpg格式的图片");
			return;
		}
		File file=new File(args[0]);
		if(!(file.exists()&&file.isFile()))
		{
			System.out.println("该文件有问题,要么不存在,要么不是文件");
			return;
		}
		if(!file.getName().endsWith(".jpg")){
			System.out.println("图片格式错误,请重新选择");
		}
		if(file.length()>1024*1024*5){
			System.out.println("文件过大,不符合要求");
			return;
		}
		//建立服务
		Socket client=new Socket("192.168.1.102",10000);
		//读一个文件
		FileInputStream fis=new FileInputStream(file);
		//获取out流,将读取的文件写入服务端
		OutputStream out=client.getOutputStream();
		//建立byte数组缓存
		byte[] buf=new byte[1024];
		int len=0;
		while((len=fis.read(buf))!=-1){
			out.write(buf,0,len);
		}
		//告诉服务端我的数据传输完毕*************一定要紧记加上标记
		client.shutdownOutput();
		
		//接受服务端给的反馈信息
		InputStream isSer=client.getInputStream();
		//建立缓冲byte数组,存储服务端发来的反馈.
		byte[] bufSer=new byte[1024];
		int lenSer=isSer.read(bufSer);
		System.out.println(new String(bufSer,0,lenSer));
		
		//关闭
		client.close();
		fis.close();
	
	}

}
class serverThread implements Runnable{
	//接受客户端
	private Socket client;
	//构造方法传递进来客户端
	serverThread(Socket client){
		this.client=client;
	}
	public void run(){
		//习惯,先,确认ip,并存储,以便多处用到
		String ip=client.getInetAddress().getHostAddress();
		String ipName=client.getInetAddress().getHostName();
		//创建一个计数器,以防,客户端发来的数据重名
		int count=1;
		try{
			System.out.println(ip+"....connected");
			//获取input流,读取传来的数据
			InputStream is=client.getInputStream();
			//建立一个文件,来本地存储读出的客户端数据
			//此处一以ip命名,ip重复后,再以计数器累加命名
			File file=new File(ip+".jpg");
			//循环判断该文件名是否存在*******************************注意了,这很吊
			while(file.exists())
					file=new File(ip+"("+(count++)+")"+".jpg");
			//建立好文件,用File流将读出的数据写入文件
			FileOutputStream fos=new FileOutputStream(file);
			//建立byte数组做缓存
			byte[] buf=new byte[1024];
			int len=0;
			while((len=is.read(buf))!=-1){
				fos.write(buf,0,len);
			}
			
			//最后给客户端发出反馈告知数据已经接受成功
			OutputStream os=client.getOutputStream();
			os.write((ipName+"数据已抵达目的地").getBytes());//给力().getBytes(),也成
			//关闭
			client.close();
			fos.close();
			
		}
		catch(Exception e){
			throw new RuntimeException(ipName+"上传失败");
		}

	}

}


class Server{
	public static void main(String[] args)throws Exception{
		//建立服务,监听一定义端口
			int port=Integer.parseInt(args[0]);
			ServerSocket server=new ServerSocket(port);
			//用循环接受客户端
			while(true){
				//主线程循环等待客户端的进入.
				Socket client=server.accept();
				//遇到一个客户端就新建一个线程,去执行他,让后主线程,在继续等待下一个客户
				new Thread(new serverThread(client)).start();
			}

	}
}

 

 ✔客户端登录,服务端实现校验

 

import java.io.*;
import java.net.*;
class LoginClient{
	public static void main(String[] args)throws Exception{
		Socket client=new Socket("127.0.0.1",10000);
		//键盘录入
		BufferedReader brin=
				new BufferedReader(new InputStreamReader(System.in));
		
		PrintWriter out=new PrintWriter(client.getOutputStream(),true);
		
		BufferedReader brser=
				new BufferedReader(new InputStreamReader(client.getInputStream()));
		
		for(int i=1;i<=3;i++){
			String line=brin.readLine();
			if(line==null)	
				break;
			out.println(line);
			
			String info=brser.readLine();
			System.out.println("info:"+info);
			if(info.contains("welcome"))
				break;
		}

		brin.close();
		client.close();
		
	}
}
class UserThread implements Runnable{
	private Socket client;
	UserThread(Socket client){
		this.client=client;
	}
	public void run(){
		//先判断ip习惯
		String ip=client.getInetAddress().getHostAddress();
		System.out.println(ip+"连接");
	try{
		for(int i=1;i<=3;i++){
			//先获得客户端发过来的信息.
			BufferedReader brcis=
					new BufferedReader(new InputStreamReader(client.getInputStream()));
					//读取并存储名字
			String name=brcis.readLine();
				//名字不能为空
				if(name==null)
					break;
			
			//为客户端反馈做准备
			PrintWriter pw=new PrintWriter(client.getOutputStream(),true);
			
			BufferedReader brcheck=new BufferedReader(new FileReader("Check.txt"));
			String line=null;
			//定义标记.记录该用户是否存在
			boolean flag=false;
			//该while循环可以结束,因为他在读一个文件.
			while((line=brcheck.readLine())!=null){
				if(line.equals(name)){
					flag=true;
					break;
				}

			}
			//根据循环后的结果,标记来判断
			if(flag)
			{
				System.out.println(name+",已登录");
				pw.println(name+",welcome");
				break;
			}
			else{
				System.out.println(name+",尝试登录");
				pw.println(name+",登录失败");
			}
			
		}
		client.close();
	}
	catch(Exception e){
		throw new RuntimeException(ip+"校验失败");
	}

}
}

class LoginServer{
	public static void main(String[] args)throws Exception{
		ServerSocket server=new ServerSocket(10000);
		while(true){
			Socket client=server.accept();
			new Thread(new UserThread(client)).start();	
		}

	}

}

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值