java模拟一个简单的QQ

v 项目源码

  https://github.com/hjzgg/java_QQ

v 标题效果

 

 

      

package testFour;import java.awt.Color;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.BindException;
import java.net.ServerSocket;
import java.util.Iterator;import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextPane;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;public class QQ {public static final int PICUTER = 1; public static final int FILE = 2; public static final int PARAGRAPH = 3; public static final int SEND = 1; public static final int RECEIVE = 2; public static final int FILEX = 3;public static int getUnusedPort() throws BindException{int port;for(port = 10000 ; port <= 65535; ++port){ServerSocket ss = null; try {ss = new ServerSocket(port);} catch (IOException e) {e.printStackTrace();}if(ss != null) break;}if(port > 65535)throw new BindException("没有可用的端口!");return port;}public synchronized static void setTextPane(JTextPane tp, byte[] bt, int len, int flag, int tag){ImageIcon myIcon = null;if(tag == SEND)myIcon = new ImageIcon("ff.jpg");else if(tag == RECEIVE)myIcon = new ImageIcon("gg.jpg");else if(tag == FILEX)myIcon = new ImageIcon("kk.jpg");SimpleAttributeSet set = new SimpleAttributeSet();Document doc = tp.getStyledDocument();if(tag == SEND || tag == RECEIVE){tp.setCaretPosition(doc.getLength());JLabel fileLabel = new JLabel("", myIcon, JLabel.CENTER);tp.insertComponent(fileLabel);}if(flag == PARAGRAPH){FontMetrics fm = tp.getFontMetrics(tp.getFont());int paneWidth = tp.getWidth();String text = new String(bt, 0, len);if( tag/3 == SEND ){StyleConstants.setForeground(set, new Color(0,255,0));//设置文字颜色StyleConstants.setFontSize(set, 15);//设置字体大小
             }else if( tag/3 == RECEIVE){StyleConstants.setForeground(set, new Color(0,0,0));//设置文字颜色StyleConstants.setFontSize(set, 15);//设置字体大小
             }try{for(int i = 0, cnt = 0; i < text.length(); ++i){if((cnt += fm.charWidth(text.charAt(i))) >= paneWidth){cnt = 0;doc.insertString(doc.getLength(), "\n", set);continue;}doc.insertString(doc.getLength(), String.valueOf(text.charAt(i)), set);}doc.insertString(doc.getLength(), "\n", set);tp.setCaretPosition(doc.getLength());//最简单的设置滚动条的位置到最后输出文本的地方//就是将JTextPane中的插入符的位置移动到文本的末端!
              }catch (BadLocationException e){}} else if(flag == PICUTER) {try{InputStream is = new ByteArrayInputStream(bt, 0, len);ImageInputStream iis = ImageIO.createImageInputStream(is);Iterator<ImageReader> itImage = ImageIO.getImageReaders(iis);if(itImage.hasNext()){ImageReader reader = itImage.next();ImageIcon ii = new ImageIcon( bt, reader.getFormatName() );tp.setCaretPosition( doc.getLength() );tp.insertComponent( new PicuterPanel(ii) );doc.insertString(doc.getLength(), "\n", set);}}catch(IOException ex){ex.printStackTrace();}catch(BadLocationException e1){}} else if(flag == FILE) {try{tp.setCaretPosition(doc.getLength());JLabel fileLabel = new JLabel(new String(bt, 0, len), myIcon, JLabel.LEFT);tp.insertComponent(fileLabel);doc.insertString(doc.getLength(), "\n", set);}catch (BadLocationException e) {e.printStackTrace();}}}
}class PicuterPanel extends JPanel{private ImageIcon ii;public PicuterPanel(ImageIcon ii){this.ii = ii;setPreferredSize(new Dimension(200, 300));setBackground(new Color(255, 255, 255));}protected void paintComponent(Graphics g) {super.paintComponent(g);g.drawImage(ii.getImage(), 0, 0, 200, 300, 0, 0, ii.getIconWidth(), ii.getIconHeight(), this);}
}
View Code
package testFour;import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ScrollPaneConstants;public class QQDialog extends Frame{private JPanel QQP = new JPanel();private JButton myFriend = new JButton("QQ好友>>");private JPanel funP = new JPanel();private JButton add = new JButton("添加好友");private JButton serach = new JButton("查询好友");private JPanel pp = new JPanel();private JPanel tmp = null;private final int QQPheight = 397;private JScrollPane jsp = new JScrollPane(QQP);private static Set<String>QQset;//IP的集合private static Map<String, QQFrame>QQmap;//IP到对通信窗口的映射private static Map<String, String>nameToIP;//姓名到IP的映射ImageIcon[] ii = new ImageIcon[3];public static Map<String, QQFrame> getMap(){return QQmap;}public static Set<String> getSet(){return QQset;}public static Map<String, String> getNameToIP(){return nameToIP;}public QQDialog(){QQset = new TreeSet<String>();QQmap = new TreeMap<String, QQFrame>();nameToIP = new TreeMap<String, String>();ii[0] = new ImageIcon("ff.jpg");ii[1] = new ImageIcon("gg.jpg");ii[2] = new ImageIcon("kk.jpg");setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));jsp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);jsp.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);pp.add(jsp);pp.setLayout(new BoxLayout(pp, BoxLayout.Y_AXIS));QQP.setLayout(new BoxLayout(QQP, BoxLayout.Y_AXIS));JPanel pmyFriend = new JPanel();pmyFriend.setLayout(new BorderLayout());pmyFriend.add(myFriend, "Center");pmyFriend.setPreferredSize(new Dimension(300, 20));add(pmyFriend);pp.setPreferredSize(new Dimension(300, 400));add(pp);add(funP);JLabel myself = null;try {myself = new JLabel(InetAddress.getLocalHost().getHostName() + ":" + InetAddress.getLocalHost().getHostAddress());} catch (UnknownHostException e) {e.printStackTrace();}addLabelListener(myself);myself.setIcon(new ImageIcon("ff.jpg"));tmp = new JPanel();tmp.setLayout(new FlowLayout(FlowLayout.CENTER));tmp.setBackground(new Color(255, 0, 255));tmp.setPreferredSize(new Dimension(250, 60));tmp.add(myself);QQP.add(tmp);funP.setLayout(new FlowLayout(FlowLayout.CENTER));funP.add(add);funP.add(serach);myFriend.addMouseListener(new MouseAdapter() {public void mouseClicked(MouseEvent e) {//将好友面板进行收缩的效果!if("QQ好友>>".equals(myFriend.getText())){QQP.setVisible(false);myFriend.setText("QQ好友<<");}else{QQP.setVisible(true);myFriend.setText("QQ好友>>");}}});add.addMouseListener(new MouseAdapter() {public void mouseClicked(MouseEvent e) {InputDialog dlg = new InputDialog();if(dlg.key == InputDialog.CANCELBTN || dlg.key== 0) return;Random rd = new Random();int index = Math.abs(rd.nextInt()) % 3;JLabel ll = new JLabel(dlg.getNameText() + ":" + dlg.getIPText(), ii[index], JLabel.LEFT);QQset.add(dlg.getIPText());//将新增加的好友添加到集合中!
                        nameToIP.put(dlg.getNameText(), dlg.getIPText());tmp = new JPanel();tmp.setLayout(new FlowLayout(FlowLayout.CENTER));tmp.setBackground(new Color(255, 0, 255));/**  BoxLayout布局简直是蛋疼的要命,一个面板X是BoxLayout布局,如果该面板添加一个面板Y的话*  那么Y就会填充X面板!如果在添加一个面板Z, 那么Y, Z就会一起布满X面板!但是可以设置Y,Z面板*  的比例! 如果X添加的是一个按钮或者标签时,还不能控制其大小.....无语了!*  *  下面的我的做法将标签添加到面板tmp中,然后再将tmp添加中QQP面板中!这样就可以控制标签的大小了!*  再添加新的面板的时候,要设置一下之前面板的PreferredSize!保证每一个标签的距离适中!*  也就是保证所有的添加的面板的高度之和 == QQP.getHeight();* */int cnt = QQP.getComponentCount();//显示QQ好友的个数!if(cnt >= 1)QQP.getComponent(cnt-1).setPreferredSize(new Dimension(250, 60));int h = QQP.getHeight() - cnt*60;if(h < 0) h=60;tmp.setPreferredSize(new Dimension(250, h));tmp.add(ll);QQP.add(tmp);QQP.add(tmp);addLabelListener(ll);//给标签添加监听器JScrollBar jsb = jsp.getVerticalScrollBar();QQP.updateUI();//利用当前外观的值重置 UI 属性。 也可以保证滚动条随时的更新//终于搞好了,将垂直滚动条自动的移动到最低端jsp.getViewport().setViewPosition(new Point(0, jsp.getVerticalScrollBar().getMaximum()));}});serach.addMouseListener(new MouseAdapter() {public void mouseClicked(MouseEvent e) {String name = JOptionPane.showInputDialog(null, "好友姓名", "好友查询", JOptionPane.OK_OPTION);if(name == null)  return ;String ip = nameToIP.get(name);if(ip == null)JOptionPane.showMessageDialog(null, "好友不存在!", "查询结果", JOptionPane.OK_OPTION);else{QQFrame fm = QQmap.get(ip);if(fm == null){try{String[] ipStr = ip.split("\\.");//将字符串中的数字分离byte[] ipBuf = new byte[4];//存储IP的byte数组for(int i = 0; i < 4; i++){ipBuf[i] = (byte)(Integer.parseInt(ipStr[i])&0xff);}fm = new QQFrame(name, ipBuf);}catch(RuntimeException ex){JOptionPane.showMessageDialog(null, ex.getMessage(), "Socket错误!", JOptionPane.OK_CANCEL_OPTION);return ;}QQmap.put(ip, fm);}else fm.requestFocus();}}});addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {if(qr == null) System.out.println("hehe");qr.setFlag();//udp服务线程停止ss.setFlag();//tcp服务线程停止System.exit(0);}});QQP.setBackground(new Color(255, 0, 255));funP.setBackground(new Color(255, 255, 0));setResizable(false);setSize(300, 500);setLocation(500, 200);setVisible(true);}public void addLabelListener(final JLabel lab){lab.setOpaque(true);lab.setBackground(new Color(255, 255, 255));lab.setPreferredSize(new Dimension(250, 55));String NameAndIP = lab.getText();String name = NameAndIP.substring(0, NameAndIP.indexOf(':'));String ip = NameAndIP.substring(NameAndIP.indexOf(':') + 1, NameAndIP.length());nameToIP.put(name, ip);QQset.add(ip);lab.addMouseListener(new MouseAdapter() {Color oldC = lab.getBackground();public void mouseEntered(MouseEvent e) {lab.setBackground(new Color(0, 255, 0));}public void mouseExited(MouseEvent e) {lab.setBackground(oldC);}public void mouseClicked(MouseEvent e) {//打开通信窗口if(e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 2){String NameAndIP = lab.getText();String name = NameAndIP.substring(0, NameAndIP.indexOf(':'));if(QQmap.get(nameToIP.get(name)) != null){//这个好友的窗口已经存在!
                                    QQmap.get(nameToIP.get(name)).requestFocus();return ;}QQFrame fm = null;try{String[] ipStr = nameToIP.get(name).split("\\.");//将字符串中的数字分离byte[] ipBuf = new byte[4];//存储IP的byte数组for(int i = 0; i < 4; i++){ipBuf[i] = (byte)(Integer.parseInt(ipStr[i])&0xff);}fm = new QQFrame(name, ipBuf);QQmap.put(nameToIP.get(name), fm);//name 和 窗口的映射!}catch(RuntimeException ex){JOptionPane.showMessageDialog(null, ex.getMessage(), "错误提示!", JOptionPane.OK_CANCEL_OPTION);return ;}}else if(e.getButton() == MouseEvent.BUTTON3){JPopupMenu pm = new JPopupMenu("胡峻峥");JMenuItem del = new JMenuItem("删除");del.setFont(new Font("华文行楷", Font.ITALIC, 20));del.setForeground(new Color(255, 0, 0));del.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {int choose = JOptionPane.showConfirmDialog(null, "确定删除!", "删除对话框", JOptionPane.YES_NO_OPTION);if(choose == JOptionPane.OK_OPTION){QQP.remove(lab.getParent());int cnt = QQP.getComponentCount();int h = QQP.getHeight() - (cnt-1)*60;if(h < 0) h=60;if(cnt >= 1)QQP.getComponent(cnt-1).setPreferredSize(new Dimension(250, h));cnt = QQP.getComponentCount();if(cnt*60 <= QQPheight)QQP.setPreferredSize(new Dimension(QQP.getWidth(), QQPheight));else QQP.setPreferredSize(new Dimension(QQP.getWidth(), cnt*60));QQP.updateUI();String NameAndIP = lab.getText();String ip = NameAndIP.substring(NameAndIP.indexOf(':') + 1);QQset.remove(ip);QQFrame fm = QQmap.get(ip);if(fm != null) fm.dispose();nameToIP.remove(NameAndIP.substring(0, NameAndIP.indexOf(':')));QQmap.remove(ip);}}});JMenuItem edit = new JMenuItem("编辑");edit.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {//得到之前的数据!String content = lab.getText();String oldName = content.substring(0, content.indexOf(':'));String oldIP = content.substring(content.indexOf(':')+1);//从新设置到文本框中InputDialog id = new InputDialog(oldIP, oldName, true);if(id.key == InputDialog.CANCELBTN || id.key== 0) return;lab.setText(id.NAME + ":" + id.IP);QQFrame fm = QQmap.get(oldIP);if(fm != null){try{fm.setSendIAD(id.IP);QQmap.put(id.IP, fm);fm.setTitle(id.NAME);QQmap.remove(oldIP);QQset.remove(oldIP);QQset.add(id.IP);nameToIP.remove(oldName);nameToIP.put(id.NAME, id.IP);}catch(RuntimeException ex){JOptionPane.showMessageDialog(null, ex.getMessage(), "修改之后的IP!", JOptionPane.OK_OPTION);}}}});edit.setFont(new Font("华文行楷", Font.ITALIC, 20));edit.setForeground(new Color(255, 0, 255));pm.setBorderPainted(true);pm.setBackground(new Color(125, 0, 125));pm.add(del);  pm.add(edit);pm.show(lab, e.getX(), e.getY());}}});}//内部类,用来访问Frame中的数据成员class InputDialog extends Dialog{private JLabel ipLabel = new JLabel("IP地址:");private JLabel nameLabel = new JLabel("姓名:");private JButton okBtn = new JButton("确定");private JButton cleBtn = new JButton("取消");private JTextField ipText = new JTextField(20);private JTextField nameText = new JTextField(20);private static final int OKBTN = 1;private static final int CANCELBTN = 2;private int key = 0;private String IP = null, NAME = null; private boolean flag = false;void initDialog(){JPanel p = null;setModal(true);setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));add(p = new JPanel());p.setLayout(new FlowLayout(FlowLayout.CENTER));ipLabel.setPreferredSize(new Dimension(50, 12));p.add(ipLabel); p.add(ipText);add(p = new JPanel());p.setLayout(new FlowLayout(FlowLayout.CENTER));nameLabel.setPreferredSize(new Dimension(50, 12));p.add(nameLabel); p.add(nameText);add(p = new JPanel());p.setLayout(new FlowLayout(FlowLayout.CENTER));p.add(okBtn); p.add(cleBtn);addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {key = 0;dispose();}});addMouseListener(new MouseAdapter() {public void mouseClicked(MouseEvent e) {requestFocus();}});okBtn.addMouseListener(new MouseAdapter() {public void mouseClicked(MouseEvent e) {key = InputDialog.OKBTN;if("".equals(ipText.getText()) || "".equals(nameText.getText()) || !checkIP(ipText.getText()) )JOptionPane.showMessageDialog(null, "信息不全或者IP填写错误!");else{String ip = ipText.getText();if(!flag && QQset.contains(ip)){JOptionPane.showMessageDialog(null, "好友已存在!", "QQ好友", JOptionPane.OK_OPTION);return ;}IP = ipText.getText();NAME = nameText.getText();dispose();}}});cleBtn.addMouseListener(new MouseAdapter() {public void mouseClicked(MouseEvent e) {key = InputDialog.CANCELBTN;dispose();}});setSize(300, 200);setLocation(200, 200);setVisible(true);}public InputDialog(String ip, String name){super(new Frame());ipText.setText(ip);nameText.setText(name);initDialog();}public InputDialog(String ip, String name, boolean flag){super(new Frame());ipText.setText(ip);nameText.setText(name);this.flag = flag;initDialog();}public InputDialog(){super(new Frame());initDialog();}public boolean checkIP(String ip){int i, begin = 0, end;for(i = 1; i <= 4; ++i){end = ip.indexOf('.', begin);if(end == -1) return false;int p = Integer.valueOf(ip.substring(begin, end));if(p < 0 || p > 255)  return false;}return true;}public String getIPText(){return IP;}public String getNameText(){return NAME;}}private static ServerSocketQQ ss = null;private static QQReceive qr = null;public static void main(String[] args){ss = new ServerSocketQQ();new Thread(ss).start();if(ServerSocketQQ.getPort() < 1) return;qr = new QQReceive();new Thread(qr).start();if(QQReceive.getPort() < 1)  return ;new QQDialog();}
}
View Code
package testFour;import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Label;
import java.awt.TextArea;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.util.Calendar;
import java.util.Iterator;
import java.util.Map;import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.filechooser.FileFilter;public class QQFrame extends Frame{private TextArea taSend = new TextArea();private JTextPane taReceive = new JTextPane();private JScrollPane p = new JScrollPane(taReceive);private JPanel pSend = new JPanel();private JPanel pReceive = new JPanel();private Label laSend = new Label("发送端.....");private Label laReceive = new Label("接收端.....");private JButton FileBtn = new JButton("传输文件");private JButton PicuterBtn = new JButton("发送图片");private InetAddress sendIAD = null;//当前窗口所对应的好友所在机器的IP对象private String QQname = null;//该对话框所对应的好友的姓名private Socket st =null;private String text;private DatagramSocket ds = null;public QQFrame(String name, byte[] ipBuf) throws RuntimeException{try {sendIAD = InetAddress.getByAddress(ipBuf);} catch (UnknownHostException e3) {throw new RuntimeException("IP错误(不存在或无发链接)!");}ds = QQReceive.getUdpSocket();if(ds == null)  throw new RuntimeException("udp Socket出错!");QQname = name;text = "";setSize(600, 600);setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));pSend.setLayout(new FlowLayout(FlowLayout.LEFT));pSend.add(laSend);pSend.add(FileBtn);pSend.add(PicuterBtn);pReceive.setLayout(new FlowLayout(FlowLayout.LEFT));pReceive.add(laReceive);taReceive.setForeground(new Color(255, 0, 255));add(pReceive);add(p);add(pSend);add(taSend);setTitle("我的好友 " + QQname);taSend.setPreferredSize(new Dimension(0, 200));taReceive.setPreferredSize(new Dimension(0, 400));taSend.setFont(new Font("仿宋", Font.PLAIN, 20));taReceive.setFont(new Font("黑体", Font.PLAIN, 25));taReceive.setEditable(false);//不能进行文本的编辑,但是可以进行访问
         taSend.addKeyListener(new KeyAdapter() {public void keyPressed(KeyEvent e) {if(e.getKeyCode() == KeyEvent.VK_ENTER){text = taSend.getText();if(text == null) return;text += "\n\n";byte[] bt = text.getBytes();DatagramPacket dp = null;try {//向指定的ip和端口发送数据~!//先说明一下数据是谁发送过来的!byte[] ip = InetAddress.getLocalHost().getHostAddress().getBytes();dp = new DatagramPacket(ip, ip.length, sendIAD, QQReceive.getPort());ds.send(dp);//这里主要是因为多可数据报包发送时会产生丢包的情况...所以暂停一段时间!try {Thread.sleep(100);} catch (InterruptedException e1) {}dp = new DatagramPacket("PARAGRAPH".getBytes(), "PARAGRAPH".getBytes().length, sendIAD, QQReceive.getPort());ds.send(dp);try {Thread.sleep(100);} catch (InterruptedException e1) {}dp = new DatagramPacket(bt, bt.length, sendIAD, QQReceive.getPort());ds.send(dp);} catch (IOException e1) {e1.printStackTrace();}synchronized(QQ.class){//发送端向接收窗口添加数据时 要 和 接收端向接收窗口添加数据时同步!byte[] x = null;try {x = new String(InetAddress.getLocalHost().getHostName() + " : ").getBytes();} catch (UnknownHostException e1) {e1.printStackTrace();}QQ.setTextPane(taReceive, x, x.length, QQ.PARAGRAPH, QQ.SEND);x = text.getBytes();QQ.setTextPane(taReceive, x, x.length, QQ.PARAGRAPH, QQ.SEND*3);taSend.requestFocus();}taSend.setText("");//发送端清空e.consume();//不让这个回车字符在输入端显示!return ;}}});addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {Map<String, QQFrame>mp = QQDialog.getMap();mp.remove(sendIAD.getHostAddress());dispose();}});FileBtn.addMouseListener(new MouseAdapter() {//文件传输public void mouseClicked(MouseEvent e) {JFileChooser jfc = new JFileChooser();jfc.showOpenDialog(null);File fl = jfc.getSelectedFile();if(fl == null) return ;try {st =  new Socket();//尝试连接对方st.connect(new InetSocketAddress(sendIAD, ServerSocketQQ.getPort()), 1000);} catch (IOException e2) {st = null;JOptionPane.showMessageDialog(null, "请求超时或连接错误!", "ServerSocket", JOptionPane.OK_CANCEL_OPTION);}if(st != null){try {byte[] bt = new byte[1024];InputStream is = st.getInputStream(); OutputStream os = st.getOutputStream();//先说明一下是谁发送过来的!byte[] ip = InetAddress.getLocalHost().getHostAddress().getBytes();os.write(ip);os.flush();try {Thread.sleep(100);} catch (InterruptedException e1) {}//向对方首先发送文件名, 然后发送文件内容!
                            os.write(fl.getName().getBytes());os.flush();try {Thread.sleep(100);} catch (InterruptedException e1) {}int len;InputStream fis = new FileInputStream(fl);while( (len = fis.read(bt)) != -1){os.write(bt, 0, len);os.flush();}bt = new String(Calendar.getInstance().getTime().toString() + ":文件已传输!").getBytes();QQ.setTextPane(taReceive, bt, bt.length, QQ.FILE, QQ.FILEX);st.shutdownOutput();//输出流结束,并标记一下,使服务端知道客户端输出已经结束了!
                            st.close();} catch (IOException e1) {e1.printStackTrace();}}}});PicuterBtn.addMouseListener(new MouseAdapter() {public void mouseClicked(MouseEvent e) {JFileChooser jfc = new JFileChooser();jfc.setFileFilter(new PicuterFilter());//设置当前的文件过滤器!jfc.setAcceptAllFileFilterUsed(false);//设置所有文件过滤器不使用!//jfc.addChoosableFileFilter(new Filter());jfc.showOpenDialog(null);//将输入流按照下面方式处理, 根据Iterator<ImageReader> itImage是否能//成功的返回一个ImageReader对象确认该流文件是否是一个图片文件!//并ImageReader类中的getFormatName()得到文件的格式!//通过最后可以通过ImageIcon的byte[]构造函数建立ImageIcon对象!//最后将图片显示在面板上!File fl = jfc.getSelectedFile();if(fl == null) return ;try{InputStream is = new FileInputStream(fl);ImageInputStream iis = ImageIO.createImageInputStream(is);Iterator<ImageReader> itImage = ImageIO.getImageReaders(iis);if(itImage.hasNext()){ImageReader reader = itImage.next();byte[] imageByte = new byte[1024*64];int len = iis.read(imageByte);if(len > 64 * 1000){JOptionPane.showMessageDialog(new Frame(), "图片过大!请采用文件传输!");return ;}DatagramPacket dp = null;//先说明一下数据是谁发送过来的!byte[] ip = InetAddress.getLocalHost().getHostAddress().getBytes();dp = new DatagramPacket(ip, ip.length, sendIAD, QQReceive.getPort());ds.send(dp);try {Thread.sleep(100);} catch (InterruptedException e1) {}dp = new DatagramPacket("PICUTER".getBytes(), "PICUTER".getBytes().length, sendIAD, QQReceive.getPort());ds.send(dp);try {Thread.sleep(100);} catch (InterruptedException e1) {}dp = new DatagramPacket(imageByte, len, sendIAD, QQReceive.getPort());ds.send(dp);synchronized(QQ.class){byte[] name = null;name = new String(InetAddress.getLocalHost().getHostName() + " : ").getBytes();QQ.setTextPane(taReceive, name, name.length, QQ.PARAGRAPH, QQ.SEND);QQ.setTextPane(taReceive, imageByte, len, QQ.PICUTER, 0);}}else throw new NoPicuterException("不是一张图片!");}catch(IOException ex){ex.printStackTrace();}}});setVisible(true);}public void setSendIAD(String ip) throws RuntimeException{String[] ipStr = ip.split("\\.");//将字符串中的数字分离byte[] ipBuf = new byte[4];//存储IP的byte数组for(int i = 0; i < 4; i++){ipBuf[i] = (byte)(Integer.parseInt(ipStr[i])&0xff);}try {sendIAD = InetAddress.getByAddress(ipBuf);} catch (UnknownHostException e3) {throw new RuntimeException("IP错误(不存在或无发链接)!");}}public DatagramSocket getDs(){return ds;}public JTextPane getReceive(){return taReceive;}}class PicuterFilter extends FileFilter {public boolean accept(File file){return(file.isDirectory() || file.getName().endsWith(".gif") || file.getName().endsWith(".png") || file.getName().endsWith(".bmp")|| file.getName().endsWith(".jpg") );/* 返回要显示的文件类型 *//**   File.isDirectory()测试此抽象路径名表示的文件是否是一个目录*/}public String getDescription() {return("Picuter Files(*.gif, *.png, *.jpg, *.bmp)");                  //返回显示文件类型的描述
      }
}class NoPicuterException extends IOException{public NoPicuterException(String x){super(x);}
}
View Code
package testFour;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.util.Map;
import java.util.Set;import javax.swing.JOptionPane;public class QQReceive implements Runnable{private QQFrame fm = null;private static DatagramSocket ds = null;private static int port = 10101;private boolean flag = true;public void setFlag(){if(ds != null)ds.close();flag = false;}public QQReceive(){try {//建立udp通信方式ds = new DatagramSocket(port);} catch (SocketException e1) {port = -1;JOptionPane.showMessageDialog(null, "DatagramSocket端口绑定错误!", "绑定错误", JOptionPane.OK_CANCEL_OPTION);}}public static DatagramSocket getUdpSocket(){return ds;} public static int getPort(){return port;}public DatagramSocket getDS(){return ds;}public void run(){if(ds == null) return ;byte[] bt = new byte[10024*10]; DatagramPacket dp = new DatagramPacket(bt, bt.length); while(flag){int flagx = 0;try {//ds.setReceiveBufferSize(size);
                    ds.receive(dp);String ip = new String(dp.getData(), 0, dp.getLength());ds.receive(dp);String tag = new String(dp.getData(), 0, dp.getLength());ds.receive(dp);Map<String, QQFrame>mp = QQDialog.getMap();Set<String>  set = QQDialog.getSet();fm = mp.get(ip);System.out.println(ip);if(set.contains(ip) && fm == null){//如果存在该好友,但是不存在对应的对话窗口//自动产生对话窗口Map<String, String> nameToIP = QQDialog.getNameToIP();String[] ipStr = ip.split("\\.");//将字符串中的数字分离byte[] ipBuf = new byte[4];//存储IP的byte数组for(int i = 0; i < 4; i++){ipBuf[i] = (byte)(Integer.parseInt(ipStr[i])&0xff);}String name = null;for(String ss : nameToIP.keySet())if( ip.equals(nameToIP.get(ss)) ){name = ss;break;}fm = new QQFrame(name, ipBuf);}else if(fm != null){fm.requestFocus();}if( tag.equals("FILE") )flagx = QQ.FILE;else if( tag.equals("PICUTER"))flagx = QQ.PICUTER;else if( tag.equals("PARAGRAPH"))flagx = QQ.PARAGRAPH;} catch (IOException e) {e.printStackTrace();}synchronized(QQ.class){if(fm == null) continue;byte[] x = new String(dp.getAddress().getHostName() + " : ").getBytes();QQ.setTextPane(fm.getReceive(), x, x.length, QQ.PARAGRAPH, QQ.RECEIVE);QQ.setTextPane(fm.getReceive(), dp.getData(), dp.getLength(), flagx, QQ.RECEIVE*3);}}}
}
View Code
package testFour;import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Calendar;
import java.util.Map;
import java.util.Set;import javax.swing.JOptionPane;public class ServerSocketQQ implements Runnable{private ServerSocket sst = null;private Socket st = null;private static int port = 10100;private boolean flag = true;public void setFlag(){if(sst != null)try {sst.close();} catch (IOException e) {e.printStackTrace();}flag = false;}public static int getPort(){return port;}public ServerSocketQQ(){//建立服务端try {sst = new ServerSocket(port);} catch (IOException e) {port = -1;JOptionPane.showMessageDialog(null, "ServerSocket端口绑定错误!", "绑定错误", JOptionPane.OK_CANCEL_OPTION);}}public void run(){byte[] bt = null;int len = 0;if(sst == null)  return ;while(true){try{//侦听并接受到此服务套接字的连接。此方法在进行连接之前一直阻塞。 创建新套接字 st = sst.accept();//得到客户端传输过来的流InputStream is = st.getInputStream();OutputStream os  = st.getOutputStream();bt = new byte[1024];len = is.read(bt);String name = new String(bt, 0, len);QQFrame fm = null;Map<String, QQFrame>mp = QQDialog.getMap();Set<String>  set = QQDialog.getSet();fm = mp.get(name);if(set.contains(name) && fm == null){//如果存在该好友,但是不存在对应的对话窗口//自动产生对话窗口Map<String, String> nameToIP = QQDialog.getNameToIP();fm = new QQFrame(name, nameToIP.get(name).getBytes());}if(fm == null){//对方不存在该好友!
                    st.close();continue;}len = is.read(bt);String fileName = new String(bt, 0, len);int choose = JOptionPane.showConfirmDialog(null, "接受或不接受", "文件传输提示", JOptionPane.YES_NO_OPTION);if(choose == JOptionPane.NO_OPTION){bt = new String(Calendar.getInstance().getTime().toString() + ":文件接受失败!").getBytes();QQ.setTextPane(fm.getReceive(), bt, bt.length, QQ.FILE, QQ.FILEX);st.close();continue;}FileOutputStream fos = new FileOutputStream( new File(fileName) );while( (len = is.read(bt)) != -1 ){//先将流文件变成byte[], 然后利用套接字的输出流发送给客户端
                     fos.write(bt);fos.flush();}bt = new String(Calendar.getInstance().getTime().toString() + ":文件接受成功!").getBytes();QQ.setTextPane(fm.getReceive(), bt, bt.length, QQ.FILE, QQ.FILEX);st.close();}catch(IOException e){e.printStackTrace();}}}}
View Code

 

转载于:https://www.cnblogs.com/hujunzheng/p/4004368.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/531620.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AC_Dream 1216 G - Beautiful People

题意&#xff1a;有n个人每人有一个力气值Si,美丽值Bi&#xff0c;满足Bi>Bj&&Si>Sj 或者 Bi<Bj&&Si<Sj 的人可以一起参见晚会&#xff0c;问最多有多少人可以一起参见晚会。思路&#xff1a; 我们根据S从小到大将所有人排序&#xff0c;然后看B最…

二级c语言程序设计bug,《C语言及程序设计》实践项目——发现Bug

返回&#xff1a;贺老师课程教学链接【项目1-sin泰勒展式中的错误】下面是sin函数的泰勒展式&#xff1a;(注&#xff1a;x取弧度值&#xff0c;而非角度值)编写了double mysin(double x)用于求sin值&#xff0c;却“死”在了123上。剧透一下&#xff0c;循环没有问题(当然问题…

AC_Dream 1224 Robbers(贪心)

题意&#xff1a;n个抢劫犯分别抢到的金钱是k1, k2, k3,...&#xff0c;一共得到的金钱是m&#xff0c; 但是在分钱的时候是按照x1/y, x2/y, x3/y,....的比例进行分配的&#xff01;这样的话 一些抢劫犯就会觉得不公平&#xff0c;不公平度为|xi/y - ki/m|(浮点运算)&#xff0…

codeforces B. Strongly Connected City(dfs水过)

题意&#xff1a;有横向和纵向的街道&#xff0c;每个街道只有一个方向&#xff0c;垂直的街道相交会产生一个节点&#xff0c;这样每个节点都有两个方向&#xff0c; 问是否每一个节点都可以由其他的节点到达.... 思路&#xff1a;规律没有想到&#xff0c;直接爆搜&#xff0…

Uvaoj 11248 Frequency Hopping(Dinic求最小割)

题意&#xff1a;1到n节点&#xff08;节点之间有一定的容量&#xff09;&#xff0c;需要流过C的流量&#xff0c;问是否可以&#xff1f;如果可以输出possible&#xff0c; 否则如果可以扩大任意一条边的容量 可以达到目的&#xff0c;那么输出possible option&#xff1a;接…

UVAoj 11324 - The Largest Clique(tarjan + dp)

题意&#xff1a;给定一个有向图&#xff0c;寻找一个点数最大集合&#xff0c;使得这个集合中的任意两个点 u,v, 都有u->v 或者 v->u 或者u<>v 思路&#xff1a;首先将强连通分量通过tarjan算法求出来&#xff0c;然后进行缩点&#xff0c;也就是每一个缩点 所组成…

hdu 2014鞍山赛区 5073 Galaxy

题意&#xff1a;就是给你 n 个数&#xff0c;代表n个星球的位置&#xff0c;每一个星球的重量都为 1 &#xff01; 开始的时候每一个星球都绕着质心转动&#xff0c;那么质心的位置就是所有的星球的位置之和 / 星球的个数 现在让你移动 k 个星球到任意位置&#xff08;多个星球…

codeforces B. Friends and Presents(二分+容斥)

题意&#xff1a;从1....v这些数中找到c1个数不能被x整除&#xff0c;c2个数不能被y整除&#xff01; 并且这c1个数和这c2个数没有相同的&#xff01;给定c1, c2, x, y&#xff0c; 求最小的v的值&#xff01; 思路&#xff1a; 二分容斥&#xff0c;二分找到v的值&#xff0c;…

Android延伸布局到状态栏,Android 状态栏透明

前言&#xff1a;最近项目大量用到状态栏透明&#xff0c;网上也出现很多库可以直接拿来用&#xff0c;个人认为没有必要那么重引用到一个库(有木有同学和我有一样的想法)&#xff0c;所以研究了一番&#xff0c;在此做个记录加强记忆也便后期查阅&#xff0c;如果无意中有幸能…

华为HarmonyOS 鸿蒙,华为鸿蒙HarmonyOS2.0手机开发者Beta版正式发布

据悉&#xff0c;本次手机开发者Beta测试支持以下中国境内主制式手机及平板电脑。手机&#xff1a;全网通(5G双卡)P40 、 全网通版P40 Pro、Mate30、Mate30(5G) 、Mate30 Pro、Mate30 Pro(5G)&#xff0c;型号清单为ANA-AN00、ELS-AN00、TAS-AL00、TAS-AN00、LIO-AL00、LIO-AN0…

android oneshot自动播放bug,移动端常见bug汇总001

前言本文是摘录整理了移动端常见的一些bug以及解决方案&#xff0c;第一篇&#xff0c;后面还会有持续的文章更新整理。点击样式闪动Q: 当你点击一个链接或者通过Javascript定义的可点击元素的时候&#xff0c;它就会出现一个半透明的灰色背景。A:根本原因是-webkit-tap-highli…

int.class 与 Integer.class

TYPE 表示的引用类型所对应的基本类型的Class对象&#xff01; 转载于:https://www.cnblogs.com/hujunzheng/p/4055471.html

android uber启动动画,模仿Uber的启动画面(上)

启动画面(Splash Screen)——不但给开发者们提供了一个尽情发挥、创建有趣动画的机会&#xff0c;也填补了App启动时从终端慢吞吞地下载数据的时间。启动画面(动态的)对于App至关重要&#xff1a;它可以让用户不失兴趣地耐心等待应用完成加载。尽管现在的启动画面多种多样&…

智慧屏用鸿蒙的生态,紧随鸿蒙OS手机版 ,智慧屏为什么对鸿蒙生态这么重要?...

原标题&#xff1a;紧随鸿蒙OS手机版 &#xff0c;智慧屏为什么对鸿蒙生态这么重要&#xff1f;12 月 21 日&#xff0c;华为正式发布了两款智慧屏新品&#xff0c;智慧屏 S 系列和车载智慧屏&#xff0c;前者是智慧屏的新系列&#xff0c;后者则是新开辟的车机产品线。没有意外…

MySQL不能插入中文字符及中文字符乱码问题

MySQL的默认编码是Latin1&#xff0c;不支持中文&#xff0c;要支持中午需要把数据库的默认编码修改为gbk或者utf8。在安装后MySQL之后&#xff0c;它的配置文件不是很给力&#xff0c;不知道你们的是不是&#xff0c;反正我的是&#xff01; 开始插入中文字符的时候出现如下错…

codeforces C. Bits(数学题+或运算)

题意&#xff1a;给定一个区间&#xff0c;求区间中的一个数&#xff0c;这个数表示成二进制的时候&#xff0c;数字1的个数最多&#xff01; 如果有多个这样的数字&#xff0c;输出最小的那个&#xff01; 思路&#xff1a;对左区间的这个数lx的二进制 从右往左将0变成1&#…

r语言 发送邮件html,r语言读取数据的方法

R 对于基于 SQL 语言的关系型数据库有良好的支持&#xff0c;这些数据库既有商业数据库 Oracle、Microsoft SQL Server、IBM DB2 等&#xff0c;也包含在 GNUGeneral Public License (GPL) 下发布的 MySQL 等开源数据库。RMySQL 包中提供了到 MySQL 数据库的接口&#xff1b;RO…

eclipse开发web应用程序步骤(图解)

*运行环境&#xff08;也就是服务器的选择&#xff09; 环境搭建好之后开始编写web程序&#xff01;然后右键->Run as -> Run on Server! 转载于:https://www.cnblogs.com/hujunzheng/p/4083560.html

android 测光模式,Android Camera1中的对焦与测光

Android Camera1开发系列连载&#xff1a;Android Camera1详解Android Camera1显示预览的四种方式对焦模式在使用特定的对焦模式的时候&#xff0c;必须确保相机支持该模式&#xff0c;相机支持的对焦模式可以通过Parameters#getFocusMode接口来获取&#xff1a;常用的对焦模式…

html5做一个展示页面,基于HTML5的WebGL实现json和echarts图表展现在同一个界面

突然有个想法&#xff0c;如果能把一些用到不同的知识点放到同一个界面上&#xff0c;并且放到一个盒子里&#xff0c;这样我如果要看什么东西就可以很直接显示出来&#xff0c;而且这个盒子一定要能打开。我用HT实现了我的想法&#xff0c;代码一百多行&#xff0c;这么少的代…