如果只进行单次传输就关闭客服端的话,就直接采用Socket中的shutdownOutput() 禁用此套接字的输出流。
如果还需还需要再给服务端发送信息,直接进行shutdownOutput() ,把输出流关了,就是不太合适了,
因为服务器要等着读取客户端发消息 (这时的read可以直接读取一个null返回,相当不再是阻塞,通过读取的值为null,如果后面的操作要用的读取的值,则会发生空指针异常。
那么,就不要再去纠结 把 关闭流后紧接着会打开流 搞入同步什么的,没必要而且还浪费时间,我之前就这么搞了下,玛德,超级复杂,还容易出错。。。
下面,介绍一种超级简单的方法:结束标记。
哈哈,很熟悉是吧!还被老师注重强调过,正因为如此被洗脑的不轻。
什么搞个复杂的字符串,跟可气的是老师还把什么时间戳给搬出来了,想法是非常好的,搞个时间戳还让我学习了半天,
嗯,觉得对自己的能力是有所提升的,还蛮欣慰的,但刚要写完,我就冲动的想砸电脑了
不就是把文件读完吗!妈的蛋,有必要一定要给个读到末尾结束标记才能停止循环吗!玛德,我读完这么大的文件不就行了吗!去你的末尾结束标记!
这么简单的问题,只能客户端在上传文件之前,告诉服务端要上传的文件大小,服务端你读完了这么多个字节,就结束读取。不用在那里等着我给你结束标记,你自己结束。
客户端从服务器上下载文件也是一样。 去他妈的时间戳
下面我是写的客户端登录服务器,并选择上传或下载,有兴趣就看,没 就算了,上面的能记住就行了!
客户端:
package com.test;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.net.Socket;
/*
* 需求:客户端连接服务端后要求输入用户名和密码进行登录
* 登录成功后,选择上传或下载or退出。
* 上传只能上传jpg格式的图片且大小小于8M
*
*
*/
public class TCPClient2 {
//创建客户端Socket服务
private static Socket s = null;
private static BufferedReader bufr = null;
private static PrintWriter pw = null;
private static PrintStream ps = null;
private static BufferedReader bufinr = null;
private static BufferedInputStream bufins = null;
private static String info = null;
TCPClient2(Socket s) throws Exception{
this.s = s ;
bufr = new BufferedReader(new InputStreamReader(System.in)); //键盘录入
bufinr = new BufferedReader(new InputStreamReader(s.getInputStream())); //字符流读取
pw = new PrintWriter(s.getOutputStream(),true); //字符流写出
register();
}
//把用户名和密码发到服务端进行校验
public static void register() throws Exception{
while(true){
System.out.print("用户名:");
String name = bufr.readLine();
System.out.print("密码:");
String key = bufr.readLine();
pw.println(name);
pw.println(key);
info = bufinr.readLine();
System.out.println(info);
if(info.contains("欢迎")){//欢迎某某用户
action();
}
}
}
//选择,不同的操作()
public static boolean select() throws Exception{
info = bufinr.readLine();
System.out.println(info);//请选择你所需要的服务(输入正确数字,没有进行处理):1,上传 2,下载 3,退出
while(true){
int no = new Integer(bufr.readLine());
pw.println(no);
info = bufinr.readLine();
//选择的操作有效
if(info.contains("准备"))
return true;
System.out.println(info);
}
}
//根据用户的选择,进行相应的操作
public static void action() throws Exception{
select();
info = bufinr.readLine(); //
System.out.println(info);
//上传文件 -- 请输入需要上传的文件:
if(info.contains("上传")){
String fileName =null;
File f = null;
while(true){
fileName = bufr.readLine();//键盘获取文件名
f = new File(fileName);
if((f.exists()))
break;
System.out.print("文件不存在或输入有误,请重新输入:");
}
long fileLength = f.length(); //以文件的大小为结束标记
pw.println(fileLength);
pw.println(fileName);
BufferedInputStream fis =
new BufferedInputStream(new FileInputStream(f));
ps = new PrintStream(new BufferedOutputStream(s.getOutputStream()),true);
byte[] buf = new byte[1024*1024*8];
int len = 0;
while((len=fis.read(buf))!=-1){
ps.write(buf,0,len);
ps.flush();
}
System.out.println(bufinr.readLine());
fis.close();
action();
}
//下载文件 --选择需要下载的文件
if(info.contains("下载")){
int count = new Integer(bufinr.readLine());
//读取服务端发来的所有可下载的文件信息
for(int x=0 ; x
服务端:
package com.test;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.net.Socket;
/*
* 需求:客户端连接服务端后要求输入用户名和密码进行登录
* 登录成功后,选择上传或下载or退出。
* 上传只能上传jpg格式的图片且大小小于8M
*
*
*/
public class TCPClient2 {
//创建客户端Socket服务
private static Socket s = null;
private static BufferedReader bufr = null;
private static PrintWriter pw = null;
private static PrintStream ps = null;
private static BufferedReader bufinr = null;
private static BufferedInputStream bufins = null;
private static String info = null;
TCPClient2(Socket s) throws Exception{
this.s = s ;
bufr = new BufferedReader(new InputStreamReader(System.in)); //键盘录入
bufinr = new BufferedReader(new InputStreamReader(s.getInputStream())); //字符流读取
pw = new PrintWriter(s.getOutputStream(),true); //字符流写出
register();
}
//把用户名和密码发到服务端进行校验
public static void register() throws Exception{
while(true){
System.out.print("用户名:");
String name = bufr.readLine();
System.out.print("密码:");
String key = bufr.readLine();
pw.println(name);
pw.println(key);
info = bufinr.readLine();
System.out.println(info);
if(info.contains("欢迎")){//欢迎某某用户
action();
}
}
}
//选择,不同的操作()
public static boolean select() throws Exception{
info = bufinr.readLine();
System.out.println(info);//请选择你所需要的服务(输入正确数字,没有进行处理):1,上传 2,下载 3,退出
while(true){
int no = new Integer(bufr.readLine());
pw.println(no);
info = bufinr.readLine();
//选择的操作有效
if(info.contains("准备"))
return true;
System.out.println(info);
}
}
//根据用户的选择,进行相应的操作
public static void action() throws Exception{
select();
info = bufinr.readLine(); //
System.out.println(info);
//上传文件 -- 请输入需要上传的文件:
if(info.contains("上传")){
String fileName =null;
File f = null;
while(true){
fileName = bufr.readLine();//键盘获取文件名
f = new File(fileName);
if((f.exists()))
break;
System.out.print("文件不存在或输入有误,请重新输入:");
}
long fileLength = f.length(); //以文件的大小为结束标记
pw.println(fileLength);
pw.println(fileName);
BufferedInputStream fis =
new BufferedInputStream(new FileInputStream(f));
ps = new PrintStream(new BufferedOutputStream(s.getOutputStream()),true);
byte[] buf = new byte[1024*1024*8];
int len = 0;
while((len=fis.read(buf))!=-1){
ps.write(buf,0,len);
ps.flush();
}
System.out.println(bufinr.readLine());
fis.close();
action();
}
//下载文件 --选择需要下载的文件
if(info.contains("下载")){
int count = new Integer(bufinr.readLine());
//读取服务端发来的所有可下载的文件信息
for(int x=0 ; x
key文件 用户 密码 自己随便写: