/*
界面形式的TCP文件上传,只有一个动作,客户端的上传按钮
事件:
1)客户端上传文件的文件名
2)客户端上传文件
3)服务端返回“上传成功”
问题是:1、3都是能成功的,但是2老是上传的文件不完整,几次就有那么一次是完整的?
*/
import java.awt.Button;
import java.awt.Color;
import java.awt.FileDialog;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.MenuItem;
import java.awt.Panel;
import java.awt.TextArea;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* <pre>
* 此程序:
* 客户端上传某一文件(比如*.txt),服务器端保存,并返回 “上传成功”信息到客户端
* </pre>
*/
class UI extends Frame
{//界面部分
private static final long serialVersionUID = 1L;
protected TextArea txtaSender;
protected TextArea txtaReceiver;
protected Button btn;
public UI(String title)
{
super(title);
init();
event();
}
private void init()
{//界面初始设置
this.setVisible(true);
this.setBounds(200, 100, 655, 460);
// this.setResizable(false);
this.setBackground(Color.gray);
Panel pnl = new Panel();
pnl.setLayout(null);
txtaReceiver = new TextArea();
txtaSender = new TextArea();
btn = new Button("发送");
txtaReceiver.setBounds(0, 0, 650, 280);
txtaSender.setBounds(0, 285, 650, 100);
btn.setBounds(0, 390, 650, 40);
txtaReceiver.setBackground(new Color(255, 204, 153));
txtaSender.setBackground(new Color(255, 255, 204));
btn.setBackground(new Color(153, 204, 255));
txtaReceiver.setFont(new Font("宋体", Font.PLAIN, 15));
txtaReceiver.setEditable(false);
pnl.add(txtaReceiver);
pnl.add(txtaSender);
pnl.add(btn);
this.add(pnl);
}
private void event()
{
this.addWindowListener(new WindowAdapter()
{
@Override
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
}
}
class TcpServer extends UI implements Runnable
{//服务端
private static final long serialVersionUID = 1L;
private ServerSocket ss;
private Socket s;
public TcpServer()
{
super("TCP_服务端");
try
{
ss = new ServerSocket(10001);
System.out.println("1");
}
catch(IOException e1)
{
System.out.println("服务端socket创建失败");
}
}
@Override
public void run()
{
event();
saveFile();//接收客户端上传的文件
}
private void event()
{
this.addWindowListener(new WindowAdapter()
{
@Override
public void windowClosing(WindowEvent e)
{
if(ss != null)
try
{
ss.close();
}
catch(IOException e1)
{
System.out.println("服务端socket关闭失败");
}
System.exit(0);
}
});
}
private void saveFile()
{// 保存客户端上传的文件
while(true)
{
try
{
System.out.println("2.1");
s = ss.accept();
new Thread(new SaveClientUploadFile(s)).start();//接收文件,多线程
}
catch(IOException e)
{
System.out.println("接收失败");
}
}
}
}
class SaveClientUploadFile implements Runnable
{//接收文件部分的多线程
private Socket s;
public SaveClientUploadFile(Socket s)
{
this.s = s;
}
@Override
public void run()
{
fun();
}
private void fun()
{
BufferedReader br = null;
PrintStream ps = null;
OutputStream out = null;
InputStream in = null;
String ip = s.getInetAddress().getHostAddress();
try
{
br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String fileName = br.readLine();//接收文件名
/*------------------------------------------------------------------------------------*/
File file = new File("D:\\" + fileName);
in = s.getInputStream();
out = new FileOutputStream(file);
System.out.println("6");
byte[] buf = new byte[1024];
int len = 0;
while((len = in.read(buf)) != -1)//接收文件
{
System.out.println(len);
out.write(buf, 0, len);
out.flush();
}
System.out.println("7");
/*------------------------------------------------------------------------------------*/
ps = new PrintStream(s.getOutputStream());
ps.println(fileName + "上传成功");// 保存完毕后,以行的形式 反馈信息
// s.shutdownInput();
}
catch(IOException e)
{
System.out.println("服务端读取客户端socket信息失败");
}
finally
{
if(out != null)
try
{
out.close();
}
catch(IOException e)
{
System.out.println("服务端关闭(" + ip + ")文件输出流失败");
}
}
}
}
class TcpClient extends UI implements Runnable
{//客户端
private static final long serialVersionUID = 1L;
private Socket s;
private MenuItem miUpload;
private FileDialog fDialogUpload;
public TcpClient(String number)
{
super("TCP_客户端" + number);
}
@Override
public void run()
{
bar();
event();
}
private void bar()
{//上传按钮
Menu mUpload = new Menu("文件");
miUpload = new MenuItem("上传");
mUpload.add(miUpload);
MenuBar mb = new MenuBar();
mb.add(mUpload);
this.setMenuBar(mb);
this.setSize(655, 480);
}
private void event()
{// 重写类UI的event方法
this.addWindowListener(new WindowAdapter()
{
@Override
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
miUpload.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
clientUpload();
}
});
}
private void clientUpload()
{// 客户端上传文件
if(fDialogUpload == null)
fDialogUpload = new FileDialog(TcpClient.this, "文件上传", FileDialog.LOAD);
fDialogUpload.setVisible(true);
String path = fDialogUpload.getDirectory();
String filename = fDialogUpload.getFile();
File file = null;
file = new File(path + filename);
if(file != null && file.exists() && file.isFile())
{
BufferedReader br = null;
PrintStream ps = null;
OutputStream out = null;
InputStream in = null;
try
{
s = new Socket("127.0.0.1", 10001);
ps = new PrintStream(s.getOutputStream());
ps.println(file.getName());// 将文件名 以行的形式 发送到服务端
/*------------------------------------------------------------------------------------*/
// System.out.println(file);
in = new FileInputStream(file);
out = s.getOutputStream();
byte[] buf = new byte[1024];
int len;
System.out.println("3");
while((len = in.read(buf)) != -1)
{
out.write(buf, 0, len);// 上传
out.flush();
}
s.shutdownOutput();// 关闭输出流 告知服务器请求结束
/*------------------------------------------------------------------------------------*/
br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String meg = br.readLine();
txtaReceiver.append("服务器发来消息" + "\r\n\t" + meg + "\r\n");
}
catch(IOException e)
{
System.out.println("客户端请求失败");
}
finally
{
if(in != null)
try
{
in.close();
}
catch(IOException e)
{
System.out.println("客户端文件读取流关闭失败");
}
if(s != null)
{
try
{
s.close();
}
catch(IOException e)
{
System.out.println("客户端端点关闭失败");
}
}
}
}
}
}
public class Main
{
public static void main(String[] args)
{
new Thread(new TcpServer()).start();
new Thread(new TcpClient("_A")).start();//客户端A
new Thread(new TcpClient("_B")).start();//客户端B
}
}
|
|