您的位置:首页 > 理论基础 > 计算机网络

javaSE网络编程 + 多线程(文件传输与在线聊天)

qq_21539671 2019-06-15 16:21 127 查看 https://blog.csdn.net/qq_21539

一、相关步骤如下:
* 1,提示输入要上传的文件路径,验证路径是否存在以及是否是文件夹
* 2,发送文件名到服务器
* 3,建立多线程的服务器
* 4,读取文件名
* 5,判断文件是否存在,将结果发回客户端
* 6,接收结果,如果存在给予提示,程序直接退出
* 7,如果不存在,定义FileInputStream读取文件,写出到网络
* 8,定义FileOutputStream,从网络读取数据,存储到本地

[code]//自定义提示信息对象
class Msg{
String satus;
String msg;
File file;
}
public class ZuoYe {
int num=0;

//下载
public void download() throws Exception {
Scanner sc = new Scanner(System.in);
System.out.println("是否下载??(   y/n )");
while(true) {
if("y".equals(sc.next())) {
System.out.println("选择以上一张图片地址");
String urls = sc.next();

File file = getFile(false);

URL url = new URL(urls);
URLConnection conn = url.openConnection();
InputStream is = conn.getInputStream();
FileOutputStream  fos = new FileOutputStream(file);
byte[] b = new byte[1024];
int len ;
while((len=is.read(b))!=-1) {
fos.write(b, 0, len);
}
fos.close();
is.close();
System.out.println("下载完成!");
}else {
break;
}
System.out.println("继续下载??(y/n)");
}
System.out.println("您已退出程序");
}
//上传
public String upload(File file) throws Exception {
num++;
System.out.println("上传中...");
FileInputStream fis = new FileInputStream(file);

InetAddress byName = InetAddress.getByName("127.0.0.1");
Socket so = new Socket(byName,6666);
OutputStream os = so.getOutputStream();
byte[] b = new byte[1024];
int len;
while((len=fis.read(b))!=-1) {
os.write(b, 0, len);
}
so.shutdownOutput();

InputStream is = so.getInputStream();
InputStreamReader Isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(Isr);
String url = br.readLine();

System.out.println("第"+num+"张图片上传完成!");
System.out.println("资源访问地址:"+url);

os.close();
so.close();
fis.close();

return url;
}
//获取用户输入并返回提示信息
public Msg print(boolean b) {
Msg msg = new Msg();
Scanner sc = new Scanner(System.in);
//文件路径
System.out.println("输入路径(绝对路径)");
String path = sc.next();
if(path.equals("exit")) {
msg.satus = "exit";
msg.msg = "退出程序";
return msg;
}

File dir = new File(path);
if(!dir.isDirectory()) {
msg.satus = "path_error";
msg.msg = "输入的不是一个文件夹,请重新输入";
return msg;
};
//文件名
System.out.println("输入文件名称(仅支持以 .jpg 或 .png 结尾的图片)");
String fileName = sc.next();
if(fileName.equals("exit")) {
msg.satus = "exit";
msg.msg = "退出程序";
return msg;
}

if(!fileName.endsWith(".jpg")&&!fileName.endsWith(".png")) {
msg.satus = "format_error";
msg.msg = "文件格式不正确";
return msg;
}
File file = new File(path+'/'+fileName);
if(b) {
if(!file.exists()) {
msg.satus = "file_error";
msg.msg = "文件不存在";
return msg;
}
}
msg.satus = "success";
msg.msg = "文件可用";
msg.file = file;
return msg;
}
//获得文件对象
public File getFile(boolean b) {
int i=1;
File file = null;
while(true) {
Msg msg = print(b);
if("exit".equals(msg.satus)) {
System.out.println(msg.msg);
break;
}else if("success".equals(msg.satus)) {
//				System.out.println("第"+ ++i +"张");
file = msg.file;
break;//多图去掉break
}else {
System.out.println(msg.msg);
continue;
}
}
return file;
}
//获得LinkedList<File>多个文件对象
public LinkedList<File> getFiles(boolean b) {
LinkedList<File> list = new  LinkedList<>();
int i=1;
File file = null;
while(true) {
Msg msg = print(b);
if("exit".equals(msg.satus)) {
System.out.println(msg.msg);
break;
}else if("success".equals(msg.satus)) {
System.out.println("第"+ ++i +"张");
file = msg.file;
list.add(file);
//				break;//多图去掉break
}else {
System.out.println(msg.msg);
continue;
}
}
return list;
}
@Test  //模拟客户端,多图上传
public void client() throws Exception {
Scanner sc = new Scanner(System.in);
LinkedList<File> list = new  LinkedList<>();
System.out.println("根据提示选择文件,输入 exit 结束选择");

list = getFiles(true);
//		while(true) {
//			File file = getFile(true);
//			String url = upload(file);
//			download(url);
//		}

if(!list.isEmpty()) {//循环实现多图上传,目前无效
for(File f :list) {
String url = upload (f);
}
download();
}

}
@Test  //模拟服务端图片上传,
//junit 无法启动线程,只能用main方法测试
public void server() throws IOException{
ServerSocket ss = new ServerSocket(6666);
while(true) {
Socket sk = ss.accept();
new Thread(new Server(sk)).start();
}
}
}

class Server implements Runnable{
Socket sk;

public Server(Socket sk) {
super();
this.sk = sk;
}

@Override
public void run() {
try {
InputStream is = sk.getInputStream();
String fname = String.valueOf(System.currentTimeMillis()/1000);
String dir ="img";
String path = "D:\\Work\\apache-tomcat-8.0.50\\webapps";
String newName = path+"\\"+dir+"\\"+fname+".jpg";
File file = new File(newName);
FileOutputStream fos = new FileOutputStream(file);
byte[] b = new byte[1024];
int len;
while((len=is.read(b))!=-1) {
fos.write(b, 0, len);
}
OutputStream os = sk.getOutputStream();

InetAddress addr = InetAddress.getLocalHost();
String url="http://"+addr.getHostAddress()+":8080/"+dir+"/"+fname+".jpg";
os.write(url.getBytes());
sk.shutdownOutput();

os.close();
fos.close();
is.close();
sk.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
执行效果

根据提示选择文件,输入 exit 结束选择

输入路径(绝对路径)

D:/web

输入文件名称(仅支持以 .jpg 或 .png 结尾的图片)

1.jpg

第2张

输入路径(绝对路径)

D:/web

输入文件名称(仅支持以 .jpg 或 .png 结尾的图片)

w.jpg

第3张

输入路径(绝对路径)

d:/web

输入文件名称(仅支持以 .jpg 或 .png 结尾的图片)

sdss.jpg

第4张

输入路径(绝对路径)

exit

退出程序

上传中...

第1张图片上传完成!

资源访问地址:http://192.168.2.183:8080/img/1560585078.jpg

上传中...

第2张图片上传完成!

资源访问地址:http://192.168.2.183:8080/img/1560585078.jpg

上传中...

第3张图片上传完成!

资源访问地址:http://192.168.2.183:8080/img/1560585078.jpg

是否下载??(   y/n )

y

选择以上一张图片地址

http://192.168.2.183:8080/img/1560585078.jpg

输入路径(绝对路径)

D:/web

输入文件名称(仅支持以 .jpg 或 .png 结尾的图片)

test001.jpg

下载完成!

继续下载??(y/n)

y

选择以上一张图片地址

http://192.168.2.183:8080/img/1560585078.jpg

输入路径(绝对路径)

D:/web

输入文件名称(仅支持以 .jpg 或 .png 结尾的图片)

test002.png

下载完成!

继续下载??(y/n)

n

您已退出程序

二、使用基于UDP的Java Socket编程,完成在线咨询功能:
1)客户向咨询人员咨询。
2)咨询人员给出回答。
3)客户和咨询人员可以一直沟通,直到客户发送bye给咨询人员。

**********在线聊天一定是多线程*********

[code]	@Test//客户端1
//	junit无法启动线程,不知为何,main方法没问题
public void client1() throws Exception{
DatagramSocket send_da = new DatagramSocket();
DatagramSocket receive_da = new DatagramSocket(1029);
Thread t = new Thread(new Send(send_da,1025));
t.setName("客服1:");
t.start();
Thread t2 = new Thread(new Receive(receive_da));
t2.setName("客户:");
t2.start();
}
@Test//客户端2
//	junit无法启动线程,不知为何,main方法没问题
public void client2() throws SocketException{
DatagramSocket send_da = new DatagramSocket();
DatagramSocket receive_da = new DatagramSocket(1025);
Thread t = new Thread(new Send(send_da,1029));
t.setName("客户:");
t.start();
Thread t2 = new Thread(new Receive(receive_da));
t2.setName("客服1:");
t2.start();

}
}
class Send implements Runnable{
DatagramSocket ds = null;
int port;
public Send(DatagramSocket ds,int port) {
super();
this.ds = ds;
this.port = port;
}

@Override
public void run() {
try {
Scanner sc = new Scanner(System.in);
while(true) {
String line = sc.nextLine();
byte[] b = line.getBytes();
InetAddress byName = InetAddress.getByName("127.0.0.1");
DatagramPacket dp = new DatagramPacket(b, 0, b.length, byName,port);
ds.send(dp);
if("bye".equalsIgnoreCase(line)){
System.out.println(Thread.currentThread().getName()+"已离开....");
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
class Receive implements Runnable{
DatagramSocket ds;
DatagramPacket dp;
public Receive(DatagramSocket ds) {
this.ds = ds;
}
@Override
public void run() {
try {
while(true){
byte[] buf = new byte[1024];
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(Thread.currentThread().getName()+str);
if("bye".equalsIgnoreCase(str)){
System.out.println(Thread.currentThread().getName()+"已离开....");
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

 

标签: