网络编程项目—— 多人聊天室->双人聊天

Posted 玛丽莲茼蒿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络编程项目—— 多人聊天室->双人聊天相关的知识,希望对你有一定的参考价值。

一、Coding前的思考和步骤梳理

1. 又开始思考这个问题,拿到一个需求,是调用java底层的代码写1000行实现,还是直接调第三方库写50行实现?

都一样。

发现第一次写shell的时候其实思考过。 

2. 应该用传输层协议还是用应用层协议实现呢? 

        之所以有这个疑惑,是因为SMTP和FTP协议貌似也能实现这一功能。但是看了几个用SMTP协议的网络工程,发现用应用层聊天这个功能实现有点大材小用了。

        用传输层实现反而更聊天的需求、也更方便,那就没有必要用应用层了吧。

3. 多人聊天而不是两人聊天,应该用TCP还是UDP还是都可以呢?

        一开始我认为应该用TCP,因为聊天内容和视频不一样,视频在路上丢失几个帧看不出来,但是用户A打出的字必须让用户B能完完整整收到,所以连接必须可靠。

        但是如果使用TCP,需要至少一个用户是在线的,这样才能连接上。所以要区分是实时聊天还是微信那样发过去就行了不用管人在不在线。

        而且,要实现群聊的话,比如群里有100个人,需要给100个人互相建立TCP连接吗?微信应该是先发给服务器,再由服务器推送给群里所有人。

        所以还是用UDP吧。

4. 多人具体实现的时候应该是一个User类多个对象还是多个User类?

        在实际开发中,应该是程序中只有一个User类,各个用户在自己主机上把.exe下载下来,用这个User类生成一个User对象。

        但是在本次模拟中,我们直接用多个User类代表多台主机,但每个类的代码是一模一样的。

每个用户既要说又要听,两个线程同时进行 ,所以开两个线程。

UserA.java

package UDPChat;

/**
 * 不通过命令行输入参数,配合UserB一起使用
 */
public class UserA 
    public static void main(String[] args) 
        new Thread(new TalkSend("localhost",8888)).start();
        //UserA开放9999端口,UserA提供对方的名字
        new Thread(new TalkReceive(9999,"买家")).start();
    

UserB.java

package UDPChat;

import java.net.DatagramSocket;

/**
 * 不通过命令行输入参数,配合UserA一起使用
 */
public class UserB 

    public static void main(String[] args) 
        new Thread(new TalkSend("localhost",9999)).start();
        //UserB开放8888端口,UserB提供对方的名字
        new Thread(new TalkReceive(8888,"客服")).start();
    

说话进程 TalkSend.java

package UDPChat;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;

public class TalkSend implements Runnable
    private String desIP;  //接收方的IP
    private int desPort;  //接收方的端口号

    public TalkSend(String desIP, int desPort) 
        this.desIP = desIP;
        this.desPort = desPort;
    

    @Override
    public void run() 
        DatagramSocket socket = null;
        try 
            //1.创建发送的socket对象
            socket = new DatagramSocket();

            String s = null;
            byte []buffer = new byte[1024];
            Scanner scanner = new Scanner(System.in);
            //持续发送
            while(true)
                //2.从控制台获得发送的内容
                if(scanner.hasNextLine())
                    s = scanner.nextLine();
                
                buffer = s.getBytes();

                //3.创建packet对象,发送数据报
                DatagramPacket packet = new DatagramPacket(buffer,0,buffer.length, InetAddress.getByName(this.desIP),this.desPort);
                socket.send(packet);

                //4.聊天结束标志
                if (s.equals("bye"))
                    break;
                
            
         catch (IOException e) 
            e.printStackTrace();
         finally 
            if(socket != null)
                //5.关闭资源
                try 
                    socket.close();
                 catch (Exception e) 
                    e.printStackTrace();
                
            
        
    

听进程 TalkReceive.java 
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class TalkReceive implements Runnable
    private int openPort; //开放的端口
    private String senderName; //发送者的昵称

    public TalkReceive(int openPort, String senderName) 
        this.openPort = openPort;
        this.senderName = senderName;
    

    @Override
    public void run() 
        DatagramSocket socket = null;
        try 
            //1.创建接收方socket
            socket = new DatagramSocket(this.openPort);

            while(true)
                //2.创建服务器端的数据报对象
                byte []data = new byte[1024];
                DatagramPacket packet = new DatagramPacket(data, 0, data.length);

                //3.套接字接收数据报
                socket.receive(packet);
                System.out.println(this.senderName + ":" + new String(packet.getData()) );

                //聊天结束标志
                if(packet.getData().toString().equals("bye"))
                    break;
                
            
         catch (IOException e) 
            e.printStackTrace();
         finally 
            if(socket != null)
                try 
                    socket.close();
                 catch (Exception e) 
                    e.printStackTrace();
                
            
        
    

以上是关于网络编程项目—— 多人聊天室->双人聊天的主要内容,如果未能解决你的问题,请参考以下文章

Java网络编程系列之基于BIO的多人聊天室设计与实现

网络编程知识使用Socket通信,做一个简单的多人聊天室

网络编程知识使用Socket通信,做一个简单的多人聊天室

Socket实现多人聊天室-未完成

C#实现多人视频聊天

java 网络编程-TCP-多人聊天(面向对象封装)