1. 程式人生 > >java 簡易聊天工具(TCP)

java 簡易聊天工具(TCP)

真的是做了特別久。這兩週剛剛學的awt和swing,順便自己翻翻舍友的《java入門到入土》,看了一些TCP相關,於是開始著手做這個聊天工具。
一開始對照書寫了一個單向的聊天工具,一個是伺服器端一個是客戶端。只可以客戶端向伺服器端發訊息
客戶端是GUI,伺服器端是CUI。

[講解]

稍微做一波講解。
有一些名詞不明白也沒關係。想搞懂就百度。

伺服器端和客戶端互動分3步驟
第一步:伺服器程式建立一個ServerSocket(伺服器套接字),呼叫accept方法等待客戶機來連線
第二步:客戶端程式建立一個Socket(套接字),請求與伺服器建立連線。
第三步:伺服器接受客戶機的連線請求,同時建立一個新的Socket與客戶建立連線。伺服器繼續等待請求。

[程式碼]

如果想看懂以下的程式碼需要的知識:
1.awt和swing(做介面的)
2.異常處理。(try…catch…)
3.I/O輸入輸出。主要是帶快取的輸入輸出(BufferedInputStream和BufferedoutputStream)
4.TCP

[小菜]
先給大家上個小菜。
使用InetAddress類的getHostName和getHostAddress方法獲得本地主機的本機名,和ip地址。

import java.net.*;
public class Main
{
    public static void main(String args[])
    {
        InetAddress ip;
        try
{ ip=InetAddress.getLocalHost(); String hostname=ip.getHostName(); String hostip=ip.getHostAddress(); System.out.println("本機名:"+hostname); System.out.println("本機ip:"+hostip); } catch (UnknownHostException e) { e.printStackTrace(); } } }

[伺服器端]

import java.io.*;
import java.net.*;

public class Main
{
    public static void main(String args[])
    {
        InetAddress ip;
        try {
            ip=InetAddress.getLocalHost();//本地ip

            System.out.println(ip.getHostAddress());
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        MyTcp tcp=new MyTcp();
        tcp.getserver();
    }
}


class MyTcp
{
    private BufferedReader reader;
    private ServerSocket server;
    private Socket socket;

    void getserver()
    {
        try
        {
            server=new ServerSocket(8998);
            System.out.println("伺服器Socket已經建立成功了");
            while(true)
            {
                System.out.println("等待客戶機連線");
                socket=server.accept();
                reader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
                getClientMessage();
            }
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
    private void getClientMessage()
    {
        try 
        {
            while(true)
            {
                System.out.println("客戶機:"+reader.readLine());
            }
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        try
        {
            if(reader!=null)
            {
                reader.close();
            }
            if(socket!=null)
            {
                socket.close();
            }
        }catch(IOException e)
        {
            e.printStackTrace();
        }
    }
}

[客戶端]

import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

import javax.swing.*;
import javax.swing.border.BevelBorder;

public class Main
{
    public static void main(String args[])
    {
        MyClien clien=new MyClien("向伺服器送資料");
        clien.setSize(600, 600);
        clien.setVisible(true);
        clien.connect();
    }
}


class MyClien extends JFrame
{
    private PrintWriter writer;
    Socket socket;
    private JTextArea ta=new JTextArea();
    private JTextField tf=new JTextField();
    Container cc;
    public MyClien(String title)
    {
        super(title);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        cc=this.getContentPane();
        final JScrollPane scrollPane =new JScrollPane();
        scrollPane.setBorder(new BevelBorder(BevelBorder.RAISED));
        getContentPane().add(scrollPane, BorderLayout.CENTER);
        scrollPane.setViewportView(ta);
        cc.add(tf, "South");
        tf.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e)
            {
                writer.println(tf.getText());
                ta.append(tf.getText()+'\n');
                ta.setSelectionEnd(ta.getText().length());
                tf.setText("");
            }
        });
    }
    void connect()
    {
        ta.append("嘗試連線\n");
        try
        {
            socket=new Socket("192.168.1.102 ",8998);
            writer=new PrintWriter(socket.getOutputStream(),true);
            ta.append("完成連線\n");
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
}

**

[雙向傳送TCP]

**
上面的程式碼是隻可以單向傳送的。
故琢磨了一個下午做了一個雙向傳送的版本。
雖然方法很蠢,但還是做出來了。
將服務端和客戶端合在一起同時向對法傳送訊息。

只需輸入對方ip和埠(我把埠定死為8998了)。
但是在JTextArea輸出的時候還是有點小bug,就是回車的問題。不過不想改了,好懶。
還有就是建議埠數用1024以上的,不然很容易和其他衝突。
上程式碼
[程式碼]

import java.awt.*;
import javax.swing.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.io.*;
import java.net.*;

public class Main
{
    static int flag=0;
    static int isgetip=0;
    static String to_ip;
    static String to_socket;
    public static void main(String args[])
    {
        String hostip_num = null;
        try {
            InetAddress ip=InetAddress.getLocalHost();
            hostip_num=ip.getHostAddress();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }

        GetInformation gi=new GetInformation(hostip_num);
        gi.display();
        MyTcp mf=new MyTcp();
        mf.display();

    }



    public static class GetInformation
    {
        JFrame jframe;
        JTextField jtf1;
        JTextField jtf2;
        JTextField jtf3;
        JLabel jl_ip;
        JLabel jl_socket;
        JLabel jl_hostip;
        JButton jb;
        MyListener handle;
        GetInformation(String ipnum)
        {
            jframe=new JFrame();
            jtf1=new JTextField();
            jtf2=new JTextField();
            jb=new JButton("確定");
            jl_hostip=new JLabel("本   機   ip:"+ipnum);
            jl_ip=new JLabel("ip   地   址:");
            jl_socket=new JLabel("埠地址:");
            handle =new MyListener();
        }
        void display()
        {
            jframe.setLayout(null);

            jl_hostip.setBounds(10, 10, 300, 30);
            jl_ip.setBounds(10, 50, 100, 30);
            jl_socket.setBounds(10, 90, 100, 30);
            jtf1.setBounds(75, 50, 150, 30);
            jtf2.setBounds(75, 90, 150, 30);
            jb.setBounds(75, 125, 70, 30);
            jb.addActionListener(handle);

            jframe.add(jb);
            jframe.add(jl_hostip);
            jframe.add(jtf1);
            jframe.add(jtf2);
            jframe.add(jl_socket);
            jframe.add(jl_ip);
            jframe.setSize(250, 200);
            jframe.setAlwaysOnTop(true);
            jframe.setVisible(true);
        }
        class MyListener implements ActionListener
        {
            public void actionPerformed(ActionEvent e) {
                if(jtf1.getText().trim().equals("")||jtf2.getText().trim().equals("")) 
                {
                    JOptionPane.showMessageDialog(null,"請輸入ip和埠!");
                }
                else 
                {
                    isgetip=1;
                    to_ip=jtf1.getText();
                    to_socket=jtf2.getText();
                    jframe.dispose();
                }
            }
        }
    }




    public static class MyTcp
    {
        private JFrame jframe;
        private JTextArea jta;
        private JTextField jtf;

        private PrintWriter writer;
        private BufferedReader reader;
        private ServerSocket server;
        private Socket socket;
        private Socket cliensocket;
        MyTcp()
        {
            jframe=new JFrame();
            jta=new JTextArea();
            jtf=new JTextField();
        }
        void display()
        {
            jframe.setLayout(null);

            jta.setBounds(10, 10, 465, 400);
            jtf.setBounds(10, 430, 465, 20);
            jta.setEditable(false);
            jtf.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e)
                {
                    if(jtf.getText().trim().equals("link")&&isgetip==1&&flag==0)
                    {
                        flag=1;
                        jta.append("嘗試連線\n");

                        try {
                            cliensocket=new Socket(to_ip,8998);
                        } catch (UnknownHostException e1) {
                            // TODO Auto-generated catch block
                            e1.printStackTrace();
                        } catch (IOException e1) {
                            // TODO Auto-generated catch block
                            e1.printStackTrace();
                        }
                        try {
                            writer=new PrintWriter(cliensocket.getOutputStream(),true);
                        } catch (IOException e1) {
                            // TODO Auto-generated catch block
                            e1.printStackTrace();
                        }

                        jta.append("完成連線\n");
                    }
                    writer.println(jtf.getText());
                    jta.append('\n'+jtf.getText()+'\n');
                    jta.setSelectionEnd(jta.getText().length());
                    jtf.setText("");
                }
            });

            jframe.add(jtf);
            jframe.add(jta);
            jframe.setSize(500, 500);
            jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            jframe.setVisible(true);
            getserver();
        }
        void getserver()
        {
            try {
                server=new ServerSocket(8998);
                jta.append("伺服器Socket已經建立成功了\n");
                while(true)
                {
                    jta.append("等待客戶機連線\n");

                    socket=server.accept();
                    reader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
                    getClientMessage();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        private void getClientMessage()
        {
            try 
            {
                while(true)
                {
                    jta.append("客戶機:"+reader.readLine());
                }
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
            try
            {
                if(reader!=null)
                {
                    reader.close();
                }
                if(socket!=null)
                {
                    socket.close();
                }
            }catch(IOException e)
            {
                e.printStackTrace();
            }
        }
    }

}


/*
if(flag==0&&isgetip==1)
{
    flag=1;
    cliensocket=new Socket(to_ip,8998);
    writer=new PrintWriter(cliensocket.getOutputStream(),true);
    jta.append("完成連線\n");
}*/


相關推薦

java 簡易聊天工具TCP

真的是做了特別久。這兩週剛剛學的awt和swing,順便自己翻翻舍友的《java入門到入土》,看了一些TCP相關,於是開始著手做這個聊天工具。 一開始對照書寫了一個單向的聊天工具,一個是伺服器端一個是客戶端。只可以客戶端向伺服器端發訊息 客戶端是GUI,伺服

實現簡易聊天

ima log body .com 麻煩 導入 定義 右鍵 正常 預備工作: (1)讀取文件的時候可能會遇到多個文件一起傳,可以用線程池。 (2)發送不同類型的請求時,如發送的是聊天信息,發送的是文件,發送的是好友上線請求等,但對於接受者來說都是字節流無法分別,這就需要我們

Java開發小工具1生成一個可執行的jar包

一、概述平常工作中難免會遇到些大量重複性沒有什麼技術含量的體力活,這時候,我們通常用程式去寫個小工具來完成,最簡單常見的就是寫個Java  Main方法,執行Main方法就可以完成相應的功能,但這樣的工

Java開發小工具2生成可雙擊執行的exe檔案

一、概述在Java開發小工具(1)中,我們已經可以生成一個可執行的jar包,這篇博文我們將這個jar包通過工具(exe4j)包裝成一個exe檔案,這樣不用在cmd中執行java -jar XXX了,可以

論持久戰之Java效能監控工具jmap

首先看一下Java官方提供的引數示例: 下面介紹三個常用引數(heap、dump、histo) -heap(to print java heap summary) ①堆配置資訊 ②堆使用資訊 -dump:(to dump jav

SQL轉Java程式碼小工具改進

因為經常在plsql寫sql然後放到java 檔案當成String去執行 所以經常要花時間格式化,然後找到了網上的一篇文章 ,工具非常不錯,特感謝原作者: 後來我做了一些小的改進 包括:1。自動去除sql的註釋 2。自動幫你自定義好變數

mapStruct java bean對映工具1

在一個成熟的工程中,尤其是現在的分散式系統中,應用與應用之間,還有單獨的應用細分模組之後,DO 一般不會讓外部依賴,這時候需要在提

Unity 簡易聊天基於TCP1

為了準備畢業設計,學習了伺服器與客戶端之間傳輸的一些簡單的知識,並跟著網路上的教程製作了一個簡易的Unity聊天室 伺服器:用C# .Net Framework寫的 結構分為:main(主函式)、Server類(用於伺服器的開啟和接收客戶端連線)、Client類(接收訊息和傳送訊息)、Message類(用

RDIFramework.NET ━ .NET快速資訊化系統開發框架 V2.8 版本━新增企業通內部簡易聊天工具

RDIFramework.NET ━ .NET快速資訊化系統開發框架 V2.8 版本 新增企業通(內部簡易聊天工具) RDIFramework.NET,基於.NET的快速資訊化系統開發、整合框架,給使用者和開發者最佳的.Net框架部署方案。      “企業通”是RDIFramework.NET框架

仿QQ聊天工具JAVA實現專案總結

一、遇到的異常及解決辦法 1.        org.hibernate.HibernateException:Could not parse configuration: /hibernate.cfg.xml ..省略 Caused by: org.dom4j.Docu

2018.4.28 基於java聊天系統帶完善

group false com opera listen nec xtend imp 選擇 Java聊天系統 1.Socket類 Socket(InetAddress address, int port) 創建一個流套接字並將其連接到指定 IP 地址的指定端口號。 S

三、Java基礎工具1_常用類——用戶和程序交互

size 數據 輸入 方法 main方法 main scanner類 style 輸入數據 2018-05-12 用戶和程序交互 程序接受用戶的輸入數據,有以下三種方式 一、main方法接受參數 二、Console 三、Scanner類 三、Java基

三、Java基礎工具1_常用類——數學相關類

ref .com 工具 www 小數 spa -- 指數 target 2018-05-13 數學相關類 一、Math類    Java 的 Math 包含了用於執行基本數學運算的屬性和方法,如初等指數、對數、平方根和三角函數。   Math 的方法都被定義為 s

三、Java基礎工具1_常用類——日期類

for 我們 size CA calendar 大量 col -- bsp 2018-05-14 日期類 一、Date類   講java.util.Date,類 Date 表示特定的瞬間,精確到毫秒。   Date類中大量方法讀已經過時,過時不代表不存在,依然可以

Java EE入門教程系列第一章Java EE的概述——Java EE技術框架和開發工具

1.3Java EE的技術框架 從技術的角度劃分,完整的Java EE分成了4個部分:元件技術、服務技術、通訊技術和架構技術。 下面給出的是一個適合初學者的體系結構簡化圖,暫時接觸不到的部分統一用“支援技術”表示,我們暫時只專注於與應用級開發相關的技術即可。 1.元件技術 這是

《自己動手寫java虛擬機器》學習筆記-----命令列工具go

     專案地址:https://github.com/gongxianshengjiadexiaohuihui 在今年三月份的時候,看過這本書,但是可能知識儲備不足,許多東西都一知半解,導致看到一半就看不下去了,現在覺得自己進步挺大的,決定重新拾起這本書,並且把

Java類集框架:Stack及Properties子類、Collections工具

Stack子類 在java.util包內可以利用stack類實現棧的功能。此類定義如下: public class Stack<E> extends Vector<E> Stack類常用方法: 方法 型別

Netty+Android搭建一個簡易聊天實現群聊和私聊

零,前言 JRBM專案中無論是好友私聊,公開聊天室,還是比賽平臺都需要用到長連線,之前沒有接觸過網路通訊等知識,更別說框架了,因此直接上手netty確實有些困難,在前期主要是在b站上看(https://www.bilibili.com/video/av26415011)這個

#java 聊天—— 給聊天室增加選單和私聊功能

#java    聊天室(二)——  給聊天室增加選單和私聊功能 在上一篇部落格裡,我們實現了用java寫了一個telnet聊天伺服器,實現了群聊功能。今天我們就來給這個聊天室新增選單,並且實現私聊功能。  1.實現目標   在使用者登入後顯示選單: 當用

Java開發小技巧:HttpClient工具

前言 大多數Java應用程式都會通過HTTP協議來呼叫介面訪問各種網路資源,JDK也提供了相應的HTTP工具包,但是使用起來不夠方便靈活,所以我們可以利用Apache的HttpClient來封裝一個具有訪問HTTP協議基本功能的高效工具類,為後續開發使用提供方便。 文章要點: HttpClient使用流程