Java TCP通信概念及实例

TCP/UDP 协议

通俗解释:

TCP协议和UDP协议的区别类似于电话系统和邮政系统。

<1>TCP:类似于电话系统,建立双向的通信通道,确定连接,话音顺序接听

<2>UDP:类似于邮政系统,发送方将信件发送到正确的地址,但并不知道准确的邮路,大多数邮件到达了目的地,个别情况一些邮件会在路上丢失。邮件不保证顺序到达目的地。

TCP套接字

Socket

  客户端的通信套接字,可指定远端IP地址、端口进行连接通信,也可以通过方法获取已连接的socket的远端IP地址、端口,以及将此socket以字节输入流和输出流的形式返回,当与数据输入流和输出流绑定,便可实现客户端的网络通信。

  构造函数均为public修饰类型,如果创建socket时发生I/O错误,均抛出IOException异常。常用构造函数如下:

Socket(InetAddress address,int port):创建一个socket并与规定的IP地址的指定的端口相连接。

Socket(String host,int port):创建一个socket并与指定主机的指定端口连接。

ServerSocket

服务器的通讯套接字,用来侦听客户端请求的连接,并为每个新连接创建一个socket对象,由此创建绑定此socket的输入流和输出流,与客户端实现网络通信。

   构造函数均为public修饰类型,如果创建socket时发生I/O错误,均抛出IOException异常。常用构造函数如下:

   ServerSocket(int port):在所给定的用来侦听的端口上建立一个服务器套接字。如果端口号为0,则在任意的空闲的端口上建立要给服务器套接字。外来连接请求的数量默认最大为50。

多线程聊天室实例

服务端Cilent

  创建ServerSocket并监听设置的端口,调用accpet()方法,直到找到对应的socket与之连接,创建一个线程为止服务。

   Launch the Application 部分为Java Swing的窗口部分。

public class ServerCilent {

    private JFrame frmServer;
    private JTextField textField;
    private JTable table;
    private JLabel lblNewLabel;
    private JButton btnRefresh;
    private JButton btnListenstart;
    private SocketManager SocketArr=new SocketManager();

    //创建 Server端
        void getServer(int port)
        {
            try {
                ServerSocket serverSocket=new ServerSocket(port);
                System.out.println("已经开启服务端");
                while(true)
                {
                    Socket socket=serverSocket.accept();
                    new W_Thread(socket).start();
                    SocketArr.add(socket);
                    SocketArr.sendClientInfo();
                }
            } catch (Exception e) {
                // TODO: handle exception
                e.printStackTrace();
            }
        }

    class W_Thread extends Thread
    {
        Socket socket=null;
        private BufferedReader reader;
        private PrintWriter writer;
        public W_Thread(Socket socket)
        {
            this.socket=socket;
        }

        public void run()
        {
            try {
                reader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
                writer=new PrintWriter(socket.getOutputStream(),true);
                String msg;
                while((msg=reader.readLine())!=null )
                {
                    System.out.println(msg);
                    SocketArr.SendtoAll(msg);
                }
            } catch (Exception e) {
                // TODO: handle exception
                e.printStackTrace();
            }

        }

    }

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    ServerCilent window = new ServerCilent();
                    window.frmServer.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public ServerCilent() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        frmServer = new JFrame();
        frmServer.setResizable(false);
        frmServer.setTitle("ServerCilent");
        frmServer.setBounds(100, 100, 452, 371);
        frmServer.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmServer.getContentPane().setLayout(null);

        JPanel panel = new JPanel();
        panel.setBorder(new TitledBorder(null, "DefaultSetting", TitledBorder.LEADING, TitledBorder.TOP, null, null));
        panel.setBounds(10, 10, 414, 66);
        frmServer.getContentPane().add(panel);
        panel.setLayout(null);

        JLabel lblPort = new JLabel("Port:");
        lblPort.setBounds(10, 25, 54, 15);
        panel.add(lblPort);

        textField = new JTextField();
        textField.setBounds(48, 22, 122, 21);
        panel.add(textField);
        textField.setColumns(10);

        btnListenstart = new JButton("Listen&Start");
        btnListenstart.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent arg0) {
                int port=Integer.parseInt(textField.getText());
                ServerCilent serverCilent=new ServerCilent();
                serverCilent.getServer(port);
                textField.setEditable(false);
                btnListenstart.setVisible(false);
            }
        });
        btnListenstart.setBounds(254, 21, 136, 23);
        panel.add(btnListenstart);

        JLabel label = new JLabel("在线人数:");
        label.setBounds(10, 298, 82, 15);
        frmServer.getContentPane().add(label);

        lblNewLabel = new JLabel(String.valueOf(SocketArr.size()));
        lblNewLabel.setBounds(75, 298, 54, 15);
        frmServer.getContentPane().add(lblNewLabel);

        btnRefresh = new JButton("Refresh");
        btnRefresh.setBounds(331, 298, 93, 23);
        frmServer.getContentPane().add(btnRefresh);
    }
}

多线程客户端Cilent

创建Socket,并获取对应的输入输出流即可。

public class Cilent implements Runnable{

    /*Swing*/
    private JFrame frmLogincilent;
    private JTextField IPAdress;
    private JTextField Port;
    private JTextField Nickname;
    private JTextField Sendinfo;
    private JButton Sumbit;
    private JTextArea ShowArea;
    private JButton Send;
    /*Stream*/
    private BufferedReader reader;
    private PrintWriter writer;

    @Override
    public void run(){
        while(true){
            try {
                ShowArea.append(reader.readLine()+"\n");
            } catch (Exception e) {
                // TODO: handle exception
            }
        }
    }

    public void Create_Socket(InetAddress ip,int port){
        ShowArea.append("正在尝试连接到服务端…… ……"+"\n");
        try {
            Socket socket=new Socket(ip, port);
            ShowArea.append("聊天室已经准备好");
            frmLogincilent.setTitle("Ip:"+ip+"   Port:"+port+"   已连接在线");
            reader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
            writer=new PrintWriter(socket.getOutputStream(),true);
            new Thread(this).start();
        } catch (Exception e) {
            // TODO: handle exception
        }
    }

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    Cilent window = new Cilent();
                    window.frmLogincilent.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public Cilent() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        frmLogincilent = new JFrame();
        frmLogincilent.setResizable(false);
        frmLogincilent.setTitle("Cilent");
        frmLogincilent.setBounds(100, 100, 458, 532);
        frmLogincilent.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmLogincilent.getContentPane().setLayout(null);

        JPanel panel = new JPanel();
        panel.setBorder(new TitledBorder(null, "Default Setting", TitledBorder.LEADING, TitledBorder.TOP, null, null));
        panel.setBounds(10, 10, 424, 84);
        frmLogincilent.getContentPane().add(panel);
        panel.setLayout(null);

        JLabel lblIpAdress = new JLabel("IP Adress:");
        lblIpAdress.setBounds(10, 20, 73, 15);
        panel.add(lblIpAdress);

        IPAdress = new JTextField();
        IPAdress.setBounds(82, 17, 142, 21);
        panel.add(IPAdress);
        IPAdress.setColumns(10);

        JLabel lblProt = new JLabel("Prot:");
        lblProt.setBounds(10, 48, 54, 15);
        panel.add(lblProt);

        Port = new JTextField();
        Port.setBounds(82, 45, 66, 21);
        panel.add(Port);
        Port.setColumns(10);

        JLabel lblNickname = new JLabel("NickName:");
        lblNickname.setBounds(170, 48, 73, 15);
        panel.add(lblNickname);

        Nickname = new JTextField();
        Nickname.setBounds(238, 45, 176, 21);
        panel.add(Nickname);
        Nickname.setColumns(10);

        Sumbit = new JButton("Lock&Login");
        Sumbit.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent arg0) {
                    try {
                        /*Create Socket*/
                        String ipString=IPAdress.getText();
                        int port=Integer.parseInt(Port.getText());
                        String Name=Nickname.getText();
                        InetAddress ip=InetAddress.getByName(ipString);
                        Create_Socket(ip, port);

                        /*Swing*/
                        IPAdress.setEditable(false);
                        Port.setEditable(false);
                        Nickname.setEditable(false);
                        Sumbit.setVisible(false);

                    } catch (Exception e) {
                        // TODO: handle exception
                        JOptionPane.showMessageDialog(null, "invalid data");
                    }
                }

        });
        Sumbit.setBounds(272, 16, 142, 23);
        panel.add(Sumbit);

        ShowArea = new JTextArea();
        ShowArea.setBounds(10, 104, 424, 358);
        frmLogincilent.getContentPane().add(ShowArea);

        Sendinfo = new JTextField();
        Sendinfo.setBounds(10, 472, 330, 21);
        frmLogincilent.getContentPane().add(Sendinfo);
        Sendinfo.setColumns(10);

        Send = new JButton("Send");
        Send.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent arg0) {
                writer.println(Nickname.getText()+":"+Sendinfo.getText());
                Sendinfo.setText("");
            }
        });
        Send.setBounds(349, 471, 85, 23);
        frmLogincilent.getContentPane().add(Send);
    }
}

Socket管理类

继承ArrayList,并添加发送的方法SendtoAll(),以及显示当前连接数目的方法SendCilentInfo()

public class SocketManager extends ArrayList{

    synchronized void add(Socket x)
    {
        super.add(x);
    }

    synchronized void remove(Socket x)
    {
        super.remove(x);
    }

    synchronized void SendtoAll(String str)
    {
        PrintWriter writer=null;
        Socket socket;
        for(int i=0;i<size();i++)
        {
            socket=(Socket)get(i);
            try {
                writer=new PrintWriter(socket.getOutputStream(),true);
                if(writer!=null)
                {
                    writer.println(str);
                }
            } catch (Exception e) {
                // TODO: handle exception
                e.printStackTrace();
            }
        }

    }

    synchronized void sendClientInfo()
    {
        String info="当前位于聊天室的人数为"+size();
        System.out.println(info);
        SendtoAll(info);
    }

}

示例效果:

时间: 2024-10-30 04:56:52

Java TCP通信概念及实例的相关文章

Java TCP网络编程 简单实例

先启动 Server 端,进入一个死循环以便一直监听某端口是否有连接请求.然后运行 Client 端,客户端发出连接请求,服务端监听到这次请求后向客户端发回接受消息,连接建立,启动一个线程去处理这次请求,然后继续死循环监听其他请求.客户端输入字符串后按回车键,向服务器发送数据.服务器读取数据后回复客户端数据.这次请求处理完毕,启动的线程消亡.如果客户端接收到 "OK" 之外的返回数据,会再次发送连接请求并发送数据,服务器会为这次连接再次启动一个线程来进行响应...直到当客户端接收到的返

java TCP通信

服务器端: public class TCPServer{ public static void main(String[]args){ ServerSocket ss  = new ServerSocket(6666); while(true){ Socket s = ss.accept(); System.out.println("a client connent!"); DataInputStream dis = new DataInputStream(ss.getInputSt

【Java TCP/IP Socket】TCP Socket通信中由read返回值造成的的死锁问题(含代码)

书上示例 在第一章<基本套接字>中,作者给出了一个TCP Socket通信的例子——反馈服务器,即服务器端直接把从客户端接收到的数据原原本本地反馈回去. 书上客户端代码如下: import java.net.Socket; import java.net.SocketException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class TCPEch

Java网络编程之TCP通信

一.概述 Socket类是Java运行clientTCP操作的基础类,这个类本身使用代码通过主机操作系统的本地TCP栈进行通信. Socket类的方法会建立和销毁连接,设置各种Socket选项. ServerSocket类是Java执行server端操作的基础类,该类执行于server,监听入站TCP连接.每一个socketserver监听server的某个port.当远程主机的client尝试连接此port时.server就被唤醒.并返回一个表示两台主机之间socket的正常Socket对象.

[Java] Tcp/udp 简单通信

本文转自  我自己的博客guozeyiblog.cn 欢迎来访 效果图: //UDP通信 import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import java.net.*; import javax.swing.*; class send extends JFrame implements ActionL

TCP通信实现对接硬件发送与接收十六进制数据 &amp; int与byte的转换原理 &amp; java中正负数的表示

今天收到的一份需求任务是对接硬件,TCP通信,并给出通信端口与数据包格式,如下: 1.首先编写了一个简单的十六进制转byte[]数组与byte[]转换16进制字符串的两个方法,如下: /** * 将十六进制的字符串转换成字节数组 * * @param hexString * @return */ public static byte[] hexStrToByteArrs(String hexString) { if (StringUtils.isEmpty(hexString)) { retur

Java 通过实现简单的TCP通信程序来理解TCP通信

概述 TCP通信能实现两台计算机之间的数据交互,通信的两端,要严格区分为客户端(Client)与服务端(Server). 两端通信的步骤 服务端程序,需要事先启动,等待客户端的连接. 客户端主动连接服务器端,连接成功才能通信.服务端不可以主动连接客户端. 在Java中,提供了两个类用于实现TCP通信程序: 客户端:java.net.Socket类表示.创建Socket对象,向服务端发出连接请求,服务端响应请求,两者建立连接开始通信. 服务端:java.net.ServerSocket类表示.创建

[C语言]一个很实用的服务端和客户端进行TCP通信的实例

本文给出一个很实用的服务端和客户端进行TCP通信的小例子.具体实现上非常简单,只是平时编写类似程序,具体步骤经常忘记,还要总是查,暂且将其记下来,方便以后参考. (1)客户端程序,编写一个文件client.c,内容如下: #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <

JAVASE02-Unit010: 多线程基础 、 TCP通信

多线程基础 . TCP通信 * 当一个方法被synchronized修饰后,那么 * 该方法称为同步方法,即:多个线程不能同时 * 进入到方法内部执行. package day10; /** * 当多线程并发操作同一资源时,由于线程切换的不确定 * 性,可能导致执行顺序的混乱,严重时可能导致系统 * 瘫痪. * @author adminitartor * */ public class SyncDemo1 { public static void main(String[] args) { f