socket网络套节字---聊天室

Posted 岸芷兰香

tags:

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

一:服务端:

1.创建客户端:

技术分享
package com.ywh.serversocket;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Set;

public class LoginThread extends Thread
{
    Socket client;
    boolean bl;
    
    //通过构造传入一个客户socket
    public LoginThread(Socket socket)
    {
        client=socket;
    }
    
    
    @Override
    public void run()
    {
        // TODO Auto-generated method stub
        try
        {
            //如果登录成功才运行发送消息的线程
            LoginServer();
            if(bl)
            {
                new SendThread(client).start();
            }
        } catch (Exception e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        
    }
    
    
    public void LoginServer()throws Exception
    {
        //将连接后客户端输入传过来的用户名进行比对确认是否存在此用户
        
        //先把传过来的用户名转换为string字符串
        InputStream input=client.getInputStream();
        byte[] bytes=new byte[1024];
        input.read(bytes);
        String str=new String(bytes);
        System.out.println(str);
        //通过Set的add方法的返回值来确认用户名是否存在,
        //若用户名存在返回值为false,不存在则将新用户名加入用户名Set为true,
        boolean b=UserInfo.nickName.add(str);
        OutputStream output=client.getOutputStream();
        
        if(b)
        {
            //当b=true,即新建用户成功时通知所有用户有新用户上线
            
            //告知当前新用户创建成功
            output.write("1".getBytes());
            //将新用户的socket和用户名存入用户名map
            UserInfo.userMap.put(client, str);
            //获取用户socket
            Set<Socket> users=UserInfo.userMap.keySet();
            for(Socket user:users)
            {
                OutputStream op=user.getOutputStream();
                op.write((str+"已上线").getBytes());
            }
            bl=true;
        }else
        {
            //若创建新用户失败,则返回false
            output.write("0".getBytes());
            LoginServer();
            bl=false;
        }
        
    }
    
    

}
JDBCUtil.java

2.创建一个类用于存储登录用户的信息:

package com.ywh.serversocket;

import java.net.Socket;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;

public class UserInfo
{
    //用来存储用户和用户名的Map
    public static HashMap<Socket, String> userMap=new HashMap<Socket, String>();
    //用于存储用户名比对的Set
    public static Set<String> nickName=new HashSet<String>();
    
}

3.交互:发送线程

技术分享
package com.ywh.serversocket;

import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.util.Set;

public class SendThread extends Thread 
{

    Socket client;

    public SendThread(Socket socket)
    {
        client = socket;
    }
    

    @Override
    public void run()
    {
        // TODO Auto-generated method stub
        while(true)
        {
            try
            {
                InputStream input=client.getInputStream();
                byte[] bytes=new byte[1024];
                input.read(bytes);
                String str=new String(bytes);
                Set<Socket> users=UserInfo.userMap.keySet();
                for(Socket user:users)
                {
                    if(user!=client)
                    {
                        user.getOutputStream().write

((UserInfo.userMap.get(client)+":"+str).getBytes());
                    }
                    
                }
                
                
            } catch (IOException e)
            {
                // TODO Auto-generated catch block
                Set<Socket> users=UserInfo.userMap.keySet();
                for(Socket user:users)
                {
                    if(user!=client)
                    {
                        try
                        {
                            user.getOutputStream

().write((UserInfo.userMap.get(client)+"下线").getBytes());
                        } catch (IOException e1)
                        {
                            // TODO Auto-generated 

catch block
                            e1.printStackTrace();
                        }
                    }
                    UserInfo.nickName.remove

(UserInfo.userMap.get(client));
                    UserInfo.userMap.remove(client);
                    
                }
                
            }
            
        }
    }
    
    

}
View Code

4.主方法,用于运行

技术分享
package com.ywh.serversocket;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class Main
{

    public static void main(String[] args)
    {
        // TODO Auto-generated method stub
        
        try
        {
            @SuppressWarnings("resource")
            ServerSocket serversocket=new ServerSocket(8088);
            System.out.println("服务器已启动...");
            
            while(true)
            {
                Socket socket=serversocket.accept();
                new LoginThread(socket).start();
            }
            
            
        } catch (IOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}
View Code

服务端完成

二:客户端部分

1.客户端发送信息

技术分享
package com.ywh.clientsocket;

import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;

public class ClientReceive extends Thread
{
    Socket client;
    public ClientReceive(Socket socket)
    {
        // TODO Auto-generated constructor stub
        client=socket;
    }
    @Override
    public void run()
    {
        // TODO Auto-generated method stub
        while(true)
        {
            try
            {
                InputStream input=client.getInputStream();
                byte[] bytes=new byte[1024];
                input.read(bytes);
                System.out.println(new String(bytes));
            } catch (IOException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
        }
    }
    
    

}
View Code

2.客户端接受信息

技术分享
package com.ywh.clientsocket;

import java.io.IOException;
import java.net.Socket;
import java.util.Scanner;

public class ClientSend extends Thread
{
    Socket client;
    
    public ClientSend(Socket socket)
    {
        // TODO Auto-generated constructor stub
        client=socket;
    }

    @Override
    public void run()
    {
        // TODO Auto-generated method stub
        @SuppressWarnings("resource")
        Scanner sc=new Scanner(System.in);
        while(true)
        {
            String str=sc.nextLine();
            try
            {
                client.getOutputStream().write(str.getBytes());
            } catch (IOException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    

}
ClientSend.java

3.客户端主方法

package com.ywh.clientsocket;

import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.util.Scanner;

public class Main
{
    public static String ip = "192.168.10.32";
    public static int port = 8088;
    static Scanner sc = new Scanner(System.in);

    public static void main(String[] args)
    {
        // TODO Auto-generated method stub
        // System.out.println("请输入IP地址");
        // String ip=sc.nextLine().trim();
        // System.out.println("请输入端口号");
        // int port=sc.nextInt();

        try
        {
            Socket user = new Socket(ip, port);
            System.out.println("连接服务器成功,请输入登录昵称");
            String nickName = sc.nextLine();
            while (nickName.equals(""))
            {
                System.out.println("昵称不能为空,请重新输入昵称");
                nickName = sc.nextLine();
            }

            Login(user,nickName);

            new ClientSend(user).start();
            new ClientReceive(user).start();

        } catch (IOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    public static void Login(Socket user, String nickName)
    {
        try
        {
            user.getOutputStream().write(nickName.getBytes());

            InputStream input = user.getInputStream();
            byte[] bytes = new byte[1024];
            input.read(bytes);
            String str = new String(bytes).trim();
            while (str.equals("0"))
            {
                System.out.println("昵称重复,请重新输入昵称");
                nickName = sc.nextLine();
                while (nickName.equals(""))
                {
                    System.out.println("昵称不能为空,请重新输入昵称");
                    nickName = sc.nextLine();
                }
                user.getOutputStream().write(nickName.getBytes());
                input = user.getInputStream();
                bytes = new byte[1024];
                input.read(bytes);
                str = new String(bytes);
            }
            if(str.equals("1"))
            {
                System.out.println("登录成功");
            }else 
            {
                System.out.println("服务器错误");
            }
        } catch (IOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}

 

以上是关于socket网络套节字---聊天室的主要内容,如果未能解决你的问题,请参考以下文章

win10下驱动级套节字通信(ksocket)

qt 实现简单聊天(一个服务器和多个客服端)

FD_SET -(转自 kakaxia6337的专栏)

WSAevent

Python--网络编程-----socket代码实例--聊天软件升级版

游戏开发实战Unity使用Socket通信实现简单的多人聊天室(万字详解 | 网络 | TCP | 通信 | Mirror | Networking)