package com.demo;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
/*主要类*/
public class myQQ {
/**
* @content socket编程
* @author qinrw
* @time 2010-11-26
*/
//定义一个框架
public talkFrame talkframe;
//定义两个线程
public PrimeThread recThread;
public sendDocThread sendThread;
public static void main(String[] arg)
{
//开始
new myQQ();
}
//初始化
public myQQ()
{
//创建两个线程
recThread = new PrimeThread();
sendThread = new sendDocThread();
//创建框架
talkframe = new talkFrame(recThread,sendThread);
talkframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
talkframe.setVisible(true);
}
//声明消息接收线程
class PrimeThread extends Thread
{
//开始
PrimeThread()
{
//do nothing
}
public void run()
{
try
{
//始终运行
while(true)
{
//定义一个字符串来获得本地端口
String stringMyPort = talkframe.dialog.getMyPort().toString();
int numMyPort = Integer.parseInt(stringMyPort);
//socket数据接收消息
DatagramSocket recSocket = new DatagramSocket(numMyPort);
//定义一个数据报数据包和一个数组来存储消息
byte[] buf = new byte[5000];
DatagramPacket recDp = new DatagramPacket(buf,buf.length);
//接收消息
recSocket.receive(recDp);
//追加到屏幕上的信息
String msg2 = new String(recDp.getData(),0,recDp.getLength()) + "/n";
talkframe.tf.append(msg2);
//睡眠
sleep(1);
//关闭socket
recSocket.close();
}//while结束
}//try结束
catch(Exception e){System.out.print(e.getMessage());}
}//run结束
}
//声明文档发送线程
class sendDocThread extends Thread
{
//构造
sendDocThread()
{
}
public void run()
{
//创建一个FileStream获取该文件中的数据
try
{
File fil = new File(talkframe.getSendDocPath());
FileInputStream fis = new FileInputStream(fil);
//创建一个服务器接受请求
ServerSocket ss = new ServerSocket(6109);
//ServerSocket ss = new ServerSocket(6109);
System.out.print("NO1");
Socket client = ss.accept();
System.out.print("NO2");
//创建一个OutputStream和数据包
OutputStream netOut = client.getOutputStream();
OutputStream doc = new DataOutputStream(new BufferedOutputStream(netOut));
//创建文件,读取缓冲区
byte[] buf = new byte[10240];
int num = fis.read(buf);
while(num != (-1))//-1表示已经到达终点
{
doc.write(buf,0,num);//讲数据写入到缓存
doc.flush();//刷新缓冲区写入数据到客户端
num = fis.read(buf);//继续读取
}
fis.close();
doc.close();
}
catch(Exception senderr){System.out.print("/nWrong!/n");}
}
}//结束class sendDocThread
}//技术class myQQ
//声明talkFrame类
class talkFrame extends JFrame
{
//定义输出区域消息
public JTextArea tf;
//定义一个portConfig类来设置端口和IP
public portConfig dialog ;
//定义两个线程的线程通过记录
public Thread theThread;
public Thread sendThread;
//定义一个字符串来存储路径
public String sendDocPath;
public String getSendDocPath()
{
return sendDocPath;
}
//构造
public talkFrame(Thread _theThread, Thread _sendThread)
{
setTitle("局域通讯");
setSize(430,350);
setResizable(false);
theThread = _theThread;
sendThread = _sendThread;
//创建frame
JTabbedPane jtb = new JTabbedPane();
tf = new JTextArea(7,30);
tf.setEditable(false);
JScrollPane scroll = new JScrollPane(tf);
scroll.setHorizontalScrollBarPolicy(
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scroll.setVerticalScrollBarPolicy(
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
jtb.addTab("内容",scroll);
add(jtb,BorderLayout.NORTH);
//按钮
JMenuBar menuBar = new JMenuBar();
setJMenuBar(menuBar);
JMenu setSys = new JMenu("点击我设置");
menuBar.add(setSys);
JMenuItem setInfo = new JMenuItem("设置");
setSys.add(setInfo);
JMenuItem setExit = new JMenuItem("退出");
setSys.add(setExit);
//创造的对话框来设置窗口和IP的
dialog = new portConfig();
//动作监听器的设置为按钮
setInfo.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
dialog.showDialog(talkFrame.this);//显示对话框
}
}
);
//动作监听器按钮的setExit
setExit.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
System.exit(0);
}
}
);
JPanel bottomPanel = new JPanel();
final JTextArea inputArea = new JTextArea(5,35);
JScrollPane scroll2 = new JScrollPane(inputArea);
scroll2.setHorizontalScrollBarPolicy(
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scroll2.setVerticalScrollBarPolicy(
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
final JTextField nickNameField = new JTextField(10);
bottomPanel.add(scroll2);
JPanel bts = new JPanel();
JButton sendDoc = new JButton("发送文件");
//动作监听器按钮的setExit
sendDoc.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
//得到的端口和IP设置对话框中的
String stringDePort = dialog.getDestiPort();
String stringDeIP = dialog.getDestiIP();
String stringMyPort= dialog.getMyPort();
//如果没有设置
if(stringDePort.equals("") ||stringDeIP.equals("")||stringMyPort.equals(""))
JOptionPane.showMessageDialog(null,"请输入端口和IP");
else
{
JFileChooser chooseFile = new JFileChooser();
int result = chooseFile.showOpenDialog(null);
chooseFile.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
if(result==JFileChooser.APPROVE_OPTION)
{
sendDocPath=chooseFile.getSelectedFile().getPath();
tf.append("/nSending " + sendDocPath +"/n");
sendThread.start();//如果端口和IP已设置启动消息的发送线程
}
}
}
});
JButton ReceiveDoc = new JButton("接受文件");
JButton send = new JButton("发送");
//ReceiveDoc监听器按钮
ReceiveDoc.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
JFileChooser chooseFile = new JFileChooser();
int result = chooseFile.showSaveDialog(null);
if(result==JFileChooser.APPROVE_OPTION)
{
//获取到的文件路径
String filePath=chooseFile.getSelectedFile().getPath();
byte[] b = new byte[10240];
System.out.print(filePath);
tf.append("/nReceiving " + filePath +"/n");
//接收文件
try
{
//接受数据并创建一个新文件
File file = new File(filePath);
file.createNewFile();
RandomAccessFile raf = new RandomAccessFile(file,"rw");
//使用socket连接到服务器
Socket server = new Socket(InetAddress.getLocalHost(),6109);
//创建一个流接受从服务器接受数据
InputStream netIn = server.getInputStream();
InputStream in = new DataInputStream(new BufferedInputStream(netIn));
//建立缓冲区
byte[] buf = new byte[10240];
int num = in.read(buf);
while(num != (-1))
{
raf.write(buf,0,num);
raf.skipBytes(num);
num = in.read(buf);
}
in.close();
raf.close();
server.close();
}
catch(Exception recd){System.out.print(recd.getMessage());}
}
}
}
);
//监听器按钮的setExit
send.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
//获取端口和IP
String stringDePort = dialog.getDestiPort();
String stringDeIP = dialog.getDestiIP();
String stringMyPort= dialog.getMyPort();
//如果没有设置
if(stringDePort.equals("") ||stringDeIP.equals("")||stringMyPort.equals(""))
JOptionPane.showMessageDialog(null,"请输入端口和IP");
else
{
int numDePort = Integer.parseInt(stringDePort);
tf.append(nickNameField.getText() + ":/n" + inputArea.getText() + "/n/n");
try
{
DatagramSocket sendSocket = new DatagramSocket();
String msg = nickNameField.getText() + ":/n" + inputArea.getText() + "/n";
DatagramPacket sendDp = new DatagramPacket(msg.getBytes(),msg.getBytes().length,InetAddress.getByName(stringDeIP),numDePort);
sendSocket.send(sendDp);
sendSocket.close();
}
catch(Exception e)
{}
}
}
});
//将按钮添加到面板
bts.add(new JLabel("设置昵称:"));
bts.add(nickNameField);
bts.add(sendDoc);
bts.add(ReceiveDoc);
bts.add(send);
bottomPanel.add(bts,BorderLayout.SOUTH);
add(bottomPanel);
}//结束构造
//如果线程已开始用一个标志来记录消息的接收
public static int flag = 0;
//一帧来设置端口和IP
class portConfig extends JPanel
{
//构造
public portConfig()
{
setLayout(new BorderLayout());
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(3,3));
panel.add(new JLabel("本地端口:"));
panel.add(port = new JTextField(""));
panel.add(new JLabel("对方的IP:"));
panel.add(toip = new JTextField(""));
panel.add(new JLabel("对方端口:"));
panel.add(toport = new JTextField(""));
add(panel,BorderLayout.NORTH);
// 创建确定和取消按钮
okButton = new JButton("确定");
okButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
//如果没有设置端口和IP
if(port.getText().equals("") ||toip.getText().equals("")||toport.getText().equals(""))
JOptionPane.showMessageDialog(null,"请输入端口和IP");
else{
if(flag == 0)//如果没启动
{
//启动这个县城
theThread.start();
flag =1;
}
ok = true;
dialog.setVisible(false);
}
}
});
JButton cancelButton = new JButton("取消");
cancelButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
dialog.setVisible(false);
}
}
);
//按钮添加到下不
JPanel buttonPanel = new JPanel();
buttonPanel.add(okButton);
buttonPanel.add(cancelButton);
add(buttonPanel,BorderLayout.SOUTH);
}
//显示在对话框Configor面板
public boolean showDialog(Component parent)
{
ok = false;
// l找到所有 frame
Frame owner = null;
if(parent instanceof Frame) owner = (Frame) parent;
else owner = (Frame) SwingUtilities.getAncestorOfClass(Frame.class, parent);
if(dialog == null || dialog.getOwner() != owner )
{
dialog = new JDialog();
dialog.add(this);
dialog.getRootPane().setDefaultButton(okButton);
dialog.pack();
}
// 设置标题和对方IP/端口
dialog.setTitle("设置");
dialog.setVisible(true);
return ok;
}
public String getDestiIP()
{
return toip.getText();
}
public String getDestiPort()
{
return toport.getText();
}
public String getMyPort()
{
return port.getText();
}
private JTextField port;//记录本地端口
private JTextField toip;//记录IP
private JTextField toport;//记录端口
private JButton okButton;
private boolean ok;//是否可见
private JDialog dialog;
}
}