Java---基于TCP协议的相互即时通讯小程序
这是几年前,新浪的一个面试题~要求是3天之内实现~ 
通过TCP 协议,建立一个服务器端。
通过配置服务器端的IP和端口: 
客户端之间就可以相互通讯~
上线了全部在线用户会收到你上线的通知。 
下线了全部的在线用户会收到你下线的通知! 
可以私聊,可以群聊。
这是第一个版本~以后有空可以再增加功能~比如传文件啊~等等~
设计思想如下:
在服务器端 用一个HashMap< userName,socket> 维护所有用户相关的信息,从而能够保证和所有的用户进行通讯。
客户端的动作: 
(1)连接(登录):发送userName    服务器的对应动作:1)界面显示,2)通知其他用户关于你登录的信息, 3)把其他在线用户的userName通知当前用户 4)开启一个线程专门为当前线程服务
(2)退出(注销):
(3)发送消息
※※发送通讯内容之后,对方如何知道是干什么,通过消息协议来实现:
客户端向服务器发的消息格式设计: 
命令关键字@#接收方@#消息内容@#发送方 
1)连接:userName      —-握手的线程serverSocket专门接收该消息,其它的由服务器新开的与客户进行通讯的socket来接收 
2)退出:exit@#全部@#null@#userName 
3)发送: on @# JList.getSelectedValue() @# tfdMsg.getText() @# tfdUserName.getText()
服务器向客户端发的消息格式设计: 
命令关键字@#发送方@#消息内容 
登录: 
   1) msg   @#server @# 用户[userName]登录了  (给客户端显示用的) 
   2) cmdAdd@#server @# userName (给客户端维护在线用户列表用的) 
退出: 
   1) msg   @#server @# 用户[userName]退出了  (给客户端显示用的) 
   2) cmdRed@#server @# userName (给客户端维护在线用户列表用的)
发送: 
   msg   @#消息发送者( msgs[3] ) @# 消息内容 (msgs[2])
服务器端源代码:
package cn.hncu;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Scanner;
import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
/**
 * 服务器
 *
 * @author 陈浩翔
 *
 * @version 1.0 2016-5-13
 */
public class ServerForm extends JFrame {
    private JList<String> list;
    private JTextArea area;
    private DefaultListModel<String> lm;
    public ServerForm() {
        JPanel p = new JPanel(new BorderLayout());
        // 最右边的用户在线列表
        lm = new DefaultListModel<String>();
        list = new JList<String>(lm);
        JScrollPane js = new JScrollPane(list);
        Border border = new TitledBorder("在线");
        js.setBorder(border);
        Dimension d = new Dimension(100, p.getHeight());
        js.setPreferredSize(d);// 设置位置
        p.add(js, BorderLayout.EAST);
        // 通知文本区域
        area = new JTextArea();
        //area.setEnabled(false);//不能选中和修改
        area.setEditable(false);
        p.add(new JScrollPane(area), BorderLayout.CENTER);
        this.getContentPane().add(p);
        // 添加菜单项
        JMenuBar bar = new JMenuBar();// 菜单条
        this.setJMenuBar(bar);
        JMenu jm = new JMenu("控制(C)");
        jm.setMnemonic('C');// 设置助记符---Alt+'C',显示出来,但不运行
        bar.add(jm);
        final JMenuItem jmi1 = new JMenuItem("开启");
        jmi1.setAccelerator(KeyStroke.getKeyStroke('R', KeyEvent.CTRL_MASK));// 设置快捷键Ctrl+'R'
        jmi1.setActionCommand("run");
        jm.add(jmi1);
        JMenuItem jmi2 = new JMenuItem("退出");
        jmi2.setAccelerator(KeyStroke.getKeyStroke('E', KeyEvent.CTRL_MASK));// 设置快捷键Ctrl+'R'
        jmi2.setActionCommand("exit");
        jm.add(jmi2);
        // 监听
        ActionListener a1 = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (e.getActionCommand().equals("run")) {
                    startServer();
                    jmi1.setEnabled(false);// 内部方法~访问的只能是final对象
                } else {
                    System.exit(0);
                }
            }
        };
        jmi1.addActionListener(a1);
        Toolkit tk = Toolkit.getDefaultToolkit();
        int width = (int) tk.getScreenSize().getWidth();
        int height = (int) tk.getScreenSize().getHeight();
        this.setBounds(width / 4, height / 4, width / 2, height / 2);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);// 关闭按钮器作用
        setVisible(true);
    }
    private static final int PORT = 9090;
    protected void startServer() {
        try {
            ServerSocket server = new ServerSocket(PORT);
            area.append("启动服务:" + server);
            new ServerThread(server).start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    // 用来保存所有在线用户的名字和Socket----池
    private Map<String, Socket> usersMap = new HashMap<String, Socket>();
    class ServerThread extends Thread {
        private ServerSocket server;
        public ServerThread(ServerSocket server) {
            this.server = server;
        }
        @Override
        public void run() {
            try {// 和客户端握手
                while (true) {
                    Socket socketClient = server.accept();
                    Scanner sc = new Scanner(socketClient.getInputStream());
                    if (sc.hasNext()) {
                        String userName = sc.nextLine();
                        area.append("\r\n用户[ " + userName + " ]登录 " + socketClient);// 在客户端通知
                        lm.addElement(userName);// 添加到用户在线列表
                        new ClientThread(socketClient).start();// 专门为这个客户端服务
                        usersMap.put(userName, socketClient);// 把当前登录的用户加到“在线用户”池中
                        msgAll(userName);// 把“当前用户登录的消息即用户名”通知给所有其他已经在线的人
                        msgSelf(socketClient);// 通知当前登录的用户,有关其他在线人的信息
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    class ClientThread extends Thread {
        private Socket socketClient;
        public ClientThread(Socket socketClient) {
            this.socketClient = socketClient;
        }
        @Override
        public void run() {
            System.out.println("一个与客户端通讯的线程启动并开始通讯...");
            try {
                Scanner sc = new Scanner(socketClient.getInputStream());
                while (sc.hasNext()) {
                    String msg = sc.nextLine();
                    System.out.println(msg);
                    String msgs[] = msg.split("@#@#");
                    //防黑
                    if(msgs.length!=4){
                        System.out.println("防黑处理...");
                        continue;
                    }
                    if("on".equals(msgs[0])){
                        sendMsgToSb(msgs);
                    }
                    if("exit".equals(msgs[0])){
                        //服务器显示
                        area.append("\r\n用户[ " + msgs[3] + " ]已退出!" + usersMap.get(msgs[3]));
                        //从在线用户池中把该用户删除
                        usersMap.remove(msgs[3]);
                        //服务器的在线列表中把该用户删除
                        lm.removeElement(msgs[3]);
                        //通知其他用户,该用户已经退出
                        sendExitMsgToAll(msgs);
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    //通知其他用户。该用户已经退出
    private void sendExitMsgToAll(String[] msgs) throws IOException {
        Iterator<String> userNames = usersMap.keySet().iterator();
        while(userNames.hasNext()){
            String userName = userNames.next();
            Socket s = usersMap.get(userName);
            PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
            String str = "msg@#@#server@#@#用户[ "+msgs[3]+" ]已退出!";
            pw.println(str);
            pw.flush();
            str = "cmdRed@#@#server@#@#"+msgs[3];
            pw.println(str);
            pw.flush();
        }
    }
    //服务器把客户端的聊天消息转发给相应的其他客户端
    public void sendMsgToSb(String[] msgs) throws IOException {
        if("全部".equals(msgs[1])){
            Iterator<String> userNames = usersMap.keySet().iterator();
            //遍历每一个在线用户,把聊天消息发给他
            while(userNames.hasNext()){
                String userName = userNames.next();
                Socket s = usersMap.get(userName);
                PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
                String str = "msg@#@#"+msgs[3]+"@#@#"+msgs[2];
                pw.println(str);
                pw.flush();
            }
        }else{
            Socket s = usersMap.get(msgs[1]);
            PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
            String str = "msg@#@#"+msgs[3]+"对你@#@#"+msgs[2];
            pw.println(str);
            pw.flush();
        }
    }
    /**
     * 把“当前用户登录的消息即用户名”通知给所有其他已经在线的人
     *
     * @param userName
     */
    // 技术思路:从池中依次把每个socket(代表每个在线用户)取出,向它发送userName
    public void msgAll(String userName) {
        Iterator<Socket> it = usersMap.values().iterator();
        while (it.hasNext()) {
            Socket s = it.next();
            try {
                PrintWriter pw = new PrintWriter(s.getOutputStream(), true);// 加true为自动刷新
                String msg = "msg@#@#server@#@#用户[ " + userName + " ]已登录!";// 通知客户端显示消息
                pw.println(msg);
                pw.flush();
                msg = "cmdAdd@#@#server@#@#" + userName;// 通知客户端在在线列表添加用户在线。
                pw.println(msg);
                pw.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * 通知当前登录的用户,有关其他在线人的信息
     *
     * @param socketClient
     */
    // 把原先已经在线的那些用户的名字发给该登录用户,让他给自己界面中的lm添加相应的用户名
    public void msgSelf(Socket socketClient) {
        try {
            PrintWriter pw = new PrintWriter(socketClient.getOutputStream(),true);
            Iterator<String> it = usersMap.keySet().iterator();
            while (it.hasNext()) {
                String msg = "cmdAdd@#@#server@#@#" + it.next();
                pw.println(msg);
                pw.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        JFrame.setDefaultLookAndFeelDecorated(true);// 设置装饰
        new ServerForm();
    }
}客户端源代码:
package cn.hncu;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
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.JTextArea;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
/**
 * 客户端
 *
 * @author 陈浩翔
 * @version 1.0 2016-5-13
 */
public class ClientForm extends JFrame implements ActionListener {
    private JTextField tfdUserName;
    private JList<String> list;
    private DefaultListModel<String> lm;
    private JTextArea allMsg;
    private JTextField tfdMsg;
    private JButton btnCon;
    private JButton btnExit;
    private JButton btnSend;
    // private static String HOST="192.168.31.168";
    private static String HOST = "127.0.0.1";// 自己机子,服务器的ip地址
    private static int PORT = 9090;// 服务器的端口号
    private Socket clientSocket;
    private PrintWriter pw;
    public ClientForm() {
        super("即时通讯工具1.0");
        // 菜单条
        addJMenu();
        // 上面的面板
        JPanel p = new JPanel();
        JLabel jlb1 = new JLabel("用户标识:");
        tfdUserName = new JTextField(10);
        // tfdUserName.setEnabled(false);//不能选中和修改
        // dtfdUserName.setEditable(false);//不能修改
        // 链接按钮
        ImageIcon icon = new ImageIcon("a.png");
        btnCon = new JButton("", icon);
        btnCon.setActionCommand("c");
        btnCon.addActionListener(this);
        // 退出按钮
        icon = new ImageIcon("b.jpg");
        btnExit = new JButton("", icon);
        btnExit.setActionCommand("exit");
        btnExit.addActionListener(this);
        btnExit.setEnabled(false);
        p.add(jlb1);
        p.add(tfdUserName);
        p.add(btnCon);
        p.add(btnExit);
        getContentPane().add(p, BorderLayout.NORTH);
        // 中间的面板
        JPanel cenP = new JPanel(new BorderLayout());
        this.getContentPane().add(cenP, BorderLayout.CENTER);
        // 在线列表
        lm = new DefaultListModel<String>();
        list = new JList<String>(lm);
        lm.addElement("全部");
        list.setSelectedIndex(0);// 设置默认显示
        list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);// 只能选中一行
        list.setVisibleRowCount(2);
        JScrollPane js = new JScrollPane(list);
        Border border = new TitledBorder("在线");
        js.setBorder(border);
        Dimension preferredSize = new Dimension(70, cenP.getHeight());
        js.setPreferredSize(preferredSize);
        cenP.add(js, BorderLayout.EAST);
        // 聊天消息框
        allMsg = new JTextArea();
        allMsg.setEditable(false);
        cenP.add(new JScrollPane(allMsg), BorderLayout.CENTER);
        // 消息发送面板
        JPanel p3 = new JPanel();
        JLabel jlb2 = new JLabel("消息:");
        p3.add(jlb2);
        tfdMsg = new JTextField(20);
        p3.add(tfdMsg);
        btnSend = new JButton("发送");
        btnSend.setEnabled(false);
        btnSend.setActionCommand("send");
        btnSend.addActionListener(this);
        p3.add(btnSend);
        this.getContentPane().add(p3, BorderLayout.SOUTH);
        // *************************************************
        // 右上角的X-关闭按钮-添加事件处理
        addWindowListener(new WindowAdapter() {
            // 适配器
            @Override
            public void windowClosing(WindowEvent e) {
                if (pw == null) {
                    System.exit(0);
                }
                String msg = "exit@#@#全部@#@#null@#@#" + tfdUserName.getText();
                pw.println(msg);
                pw.flush();
                System.exit(0);
            }
        });
        setBounds(300, 300, 400, 300);
        setVisible(true);
    }
    private void addJMenu() {
        JMenuBar menuBar = new JMenuBar();
        this.setJMenuBar(menuBar);
        JMenu menu = new JMenu("选项");
        menuBar.add(menu);
        JMenuItem menuItemSet = new JMenuItem("设置");
        JMenuItem menuItemHelp = new JMenuItem("帮助");
        menu.add(menuItemSet);
        menu.add(menuItemHelp);
        menuItemSet.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                final JDialog dlg = new JDialog(ClientForm.this);// 弹出一个界面
                // 不能直接用this
                dlg.setBounds(ClientForm.this.getX()+20, ClientForm.this.getY()+30,
                        350, 150);
                dlg.setLayout(new FlowLayout());
                dlg.add(new JLabel("服务器IP和端口:"));
                final JTextField tfdHost = new JTextField(10);
                tfdHost.setText(ClientForm.HOST);
                dlg.add(tfdHost);
                dlg.add(new JLabel(":"));
                final JTextField tfdPort = new JTextField(5);
                tfdPort.setText(""+ClientForm.PORT);
                dlg.add(tfdPort);
                JButton btnSet = new JButton("设置");
                dlg.add(btnSet);
                btnSet.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        String ip = tfdHost.getText();//解析并判断ip是否合法
                        String strs[] = ip.split("\\.");
                        if(strs==null||strs.length!=4){
                            JOptionPane.showMessageDialog(ClientForm.this, "IP类型有误!");
                            return ;
                        }
                        try {
                            for(int i=0;i<4;i++){
                                int num = Integer.parseInt(strs[i]);
                                if(num>255||num<0){
                                    JOptionPane.showMessageDialog(ClientForm.this, "IP类型有误!");
                                    return ;
                                }
                            }
                        } catch (NumberFormatException e2) {
                            JOptionPane.showMessageDialog(ClientForm.this, "IP类型有误!");
                            return ;
                        }
                        ClientForm.HOST=tfdHost.getText();//先解析并判断ip是否合法
                        try {
                            int port = Integer.parseInt( tfdPort.getText() );
                            if(port<0||port>65535){
                                JOptionPane.showMessageDialog(ClientForm.this, "端口范围有误!");
                                return ;
                            }
                        } catch (NumberFormatException e1) {
                            JOptionPane.showMessageDialog(ClientForm.this, "端口类型有误!");
                            return ;
                        }
                        ClientForm.PORT=Integer.parseInt( tfdPort.getText() );
                        dlg.dispose();//关闭这个界面
                    }
                });
                dlg.setVisible(true);//显示出来
            }
        });
        menuItemHelp.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JDialog dlg = new JDialog(ClientForm.this);
                dlg.setBounds(ClientForm.this.getX()+30,ClientForm.this.getY()+30, 400, 100);
                dlg.setLayout(new FlowLayout());
                dlg.add(new JLabel("版本所有@陈浩翔.2016.5.16 我的主页:http://chenhaoxiang.github.io"));
                dlg.setVisible(true);
            }
        });
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getActionCommand().equals("c")) {
            if (tfdUserName.getText() == null
                    || tfdUserName.getText().trim().length() == 0
                    || "@#@#".equals(tfdUserName.getText())
                    || "@#".equals(tfdUserName.getText())) {
                JOptionPane.showMessageDialog(this, "用户名输入有误,请重新输入!");
                return;
            }
            connecting();// 连接服务器的动作
            if (pw == null) {
                JOptionPane.showMessageDialog(this, "服务器未开启或网络未连接,无法连接!");
                return;
            }
            ((JButton) (e.getSource())).setEnabled(false);
            // 获得btnCon按钮--获得源
            // 相当于btnCon.setEnabled(false);
            btnExit.setEnabled(true);
            btnSend.setEnabled(true);
            tfdUserName.setEditable(false);
        } else if (e.getActionCommand().equals("send")) {
            if (tfdMsg.getText() == null
                    || tfdMsg.getText().trim().length() == 0) {
                return;
            }
            String msg = "on@#@#" + list.getSelectedValue() + "@#@#"
                    + tfdMsg.getText() + "@#@#" + tfdUserName.getText();
            pw.println(msg);
            pw.flush();
            // 将发送消息的文本设为空
            tfdMsg.setText("");
        } else if (e.getActionCommand().equals("exit")) {
            //先把自己在线的菜单清空
            lm.removeAllElements();
            sendExitMsg();
            btnCon.setEnabled(true);
            btnExit.setEnabled(false);
            tfdUserName.setEditable(true);
        }
    }
    // 向服务器发送退出消息
    private void sendExitMsg() {
        String msg = "exit@#@#全部@#@#null@#@#" + tfdUserName.getText();
        System.out.println("退出:" + msg);
        pw.println(msg);
        pw.flush();
    }
    private void connecting() {
        try {
            // 先根据用户名防范
            String userName = tfdUserName.getText();
            if (userName == null || userName.trim().length() == 0) {
                JOptionPane.showMessageDialog(this, "连接服务器失败!\r\n用户名有误,请重新输入!");
                return;
            }
            clientSocket = new Socket(HOST, PORT);// 跟服务器握手
            pw = new PrintWriter(clientSocket.getOutputStream(), true);// 加上自动刷新
            pw.println(userName);// 向服务器报上自己的用户名
            this.setTitle("用户[ " + userName + " ]上线...");
            new ClientThread().start();// 接受服务器发来的消息---一直开着的
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    class ClientThread extends Thread {
        @Override
        public void run() {
            try {
                Scanner sc = new Scanner(clientSocket.getInputStream());
                while (sc.hasNextLine()) {
                    String str = sc.nextLine();
                    String msgs[] = str.split("@#@#");
                    System.out.println(tfdUserName.getText() + ": " + str);
                    if ("msg".equals(msgs[0])) {
                        if ("server".equals(msgs[1])) {// 服务器发送的官方消息
                            str = "[ 通知 ]:" + msgs[2];
                        } else {// 服务器转发的聊天消息
                            str = "[ " + msgs[1] + " ]说: " + msgs[2];
                        }
                        allMsg.append("\r\n" + str);
                    }
                    if ("cmdAdd".equals(msgs[0])) {
                        boolean eq = false;
                        for (int i = 0; i < lm.getSize(); i++) {
                            if (lm.getElementAt(i).equals(msgs[2])) {
                                eq = true;
                            }
                        }
                        if (!eq) {
                            lm.addElement(msgs[2]);// 用户上线--添加
                        }
                    }
                    if ("cmdRed".equals(msgs[0])) {
                        lm.removeElement(msgs[2]);// 用户离线了--移除
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) {
        JFrame.setDefaultLookAndFeelDecorated(true);// 设置装饰
        new ClientForm();
    }
}Java---基于TCP协议的相互即时通讯小程序的更多相关文章
- JAVA 基于TCP协议的一对一,一对多文件传输实现
		最近老师给我们上了多线程和TCP和UDP协议,其中一个要求就是我们用JAVA协议一个基于TCP和UDP这两种协议的一对一文件上传和一对多文件上传. 然后我就开始分析TCP和UDP这两个协议的特点,发现 ... 
- 通过python的socket库实现简易即时通讯小程序
		前言 最近学习了一下有关tcp协议和socket有关的知识,看到许多socket实战都喜欢教如何做一个聊天程序,于是想着试试能不能不看教程自己写一个.当然我没太多时间做一个像qq一样的ui界面,所以做 ... 
- 基于Tcp协议的简单Socket通信实例(JAVA)
		好久没写博客了,前段时间忙于做项目,耽误了些时间,今天开始继续写起~ 今天来讲下关于Socket通信的简单应用,关于什么是Socket以及一些网络编程的基础,这里就不提了,只记录最简单易懂实用的东西. ... 
- 基于TCP协议的网络通讯流程
		不多说了,先上个图: 从上面的图中可以看出来,基于TCP协议进行通讯可以大致分成以下几个阶段: 1. 首先是在服务器端, TCP Sever调用socket(), bind(), listen()完成 ... 
- 网络编程——基于TCP协议的Socket编程,基于UDP协议的Socket编程
		Socket编程 目前较为流行的网络编程模型是客户机/服务器通信模式 客户进程向服务器进程发出要求某种服务的请求,服务器进程响应该请求.如图所示,通常,一个服务器进程会同时为多个客户端进程服务,图中服 ... 
- (1)线程的同步机制    (2)网络编程的常识    (3)基于tcp协议的编程模型
		1.线程的同步机制(重点)1.1 基本概念 当多个线程同时访问同一种共享资源时可能会造成数据的覆盖和不一致等问题,此时就需要对线程之间进行协调和通信,该方式就叫线程的同步机制. 如: 2003年左右 ... 
- (1)网络编程的常识    (2)基于tcp协议的编程模型    (3)tcp协议和udp协议的比较    (4)基于udp协议的编程模型
		1.网络编程的常识 目前主流的网络通讯软件有:微信.QQ.YY.陌陌.探探.飞信.阿里旺旺.... 在吗? 1.1 七层网络模型(熟悉) 为了保证数据传递的可靠安全等等,ISO(国际标准委员会组织)将 ... 
- 基于TCP协议的网络通信
		TCP/IP通信协议是一种可靠的网络协议,它在通信的两端各建立一个Socket,从而在通信的两端之间形成网络虚拟链路,一旦建立了虚拟的网络链路,两端的程序就可以通过虚拟链路进行通信.Java对基于TC ... 
- 浅析C#基于TCP协议的SCOKET通信
		TCP协议是一个基本的网络协议,基本上所有的网络服务都是基于TCP协议的,如HTTP,FTP等等,所以要了解网络编程就必须了解基于TCP协议的编程.然而TCP协议是一个庞杂的体系,要彻底的弄清楚它的实 ... 
随机推荐
- 使用LuaInterface遇到的编码问题
			今天使用LuaInterface加载脚本时忽然报“未知字符”错误信息!于是检查文件编码 将其修改为“US ASCII” 就好了. 
- Android Studio 2.2 HTTP proxy setting 提示异常
			操作系统 :MacOS 10.11.6 IDE :Android Studio 2.2 Java Version :1.8 异常现象描述: 在给Android Studio 2.2设置代理时,出现警告 ... 
- Http请求通信(工具类)
			Http请求通信(工具类) 异步消息处理流程是: 首先需要在主线程当中创建一个Handle对象,并重写handlerMessage()方法. 然后当子线程中需要进行UI操作时,就创建一个Message ... 
- HttpServletRequest 获取URL的方法及区别
			HttpServletRequest 获取请求的URL的方法有: 1.request.getRequestURL() 返回的是完整的url,包括Http协议,端口号,servlet名字和映射路径,但它 ... 
- IE   str.trim() 不兼容问题解决方法
			本文实例分析了javascript在IE下trim函数无法使用的解决方法: 首先,javascript的trim函数在firefox或者chrome下面使用没有问题: 1 2 3 4 5 <sc ... 
- OC加强-day01
			#pragma mark - 00 知识回顾 1.@property + 类型 + 属性名 :执行的结果 1>在类的.m里面生成一个_属性名的属性 2>生成 _属性名 这个属性的set/g ... 
- O-C相关-03:面向对象概念的具体介绍
			1.面向对象的概念 面向对象(object-oriented ;简称: OO) 至今还没有统一的概念,我这里把它定义为:按人们认识客观世界的系统思维方式,采用基于对象(实体)的概念建立模型,模拟客观世 ... 
- 0-C相关01:NSlog函数介绍。
			NSlog()函数介绍: 首先:NSlog()函数是cocoa的框架中提供的一个方法: 下图中最上方是它在Xcode中的路径: : 同样都是输出函数.下边我们来看一下,在O-C中NSlog()和在 ... 
- 冒泡排序--c#
			//冒泡排序 Console.WriteLine("请输入一个程序的数值"); int[] array = { 111, 2, 5, 32, 321 }; int temp = 0 ... 
- 菜鸟日记之 java中的集合框架
			java中的集合框架图 如图所示:java中的集合分为两种Collection和Map两种接口 可分为Collection是单列集合和Map的双列集合 Collection单列集合:继承了Iterat ... 
