当前位置 : 主页 > 编程语言 > java >

网络通信之多人聊天室

来源:互联网 收集:自由互联 发布时间:2022-08-10
/* *作者:呆萌老师 *☑csdn认证讲师 *☑51cto高级讲师 *☑腾讯课堂认证讲师 *☑网易云课堂认证讲师 *☑华为开发者学堂认证讲师 *☑爱奇艺千人名师计划成员 *在这里给大家分享技术、知


 

/*
*作者:呆萌老师
*☑csdn认证讲师
*☑51cto高级讲师
*☑腾讯课堂认证讲师
*☑网易云课堂认证讲师
*☑华为开发者学堂认证讲师
*☑爱奇艺千人名师计划成员
*在这里给大家分享技术、知识和生活
*各种干货,记得关注哦!
*/

网络通信之多人聊天室_java

        基于TCP协议书写的服务端,服务端开启之后,只能给一个客户端提供服务,在服务结束之后,服务端就关闭了,其他的客户端就无法在连接到当前这个服务端。

解决一个服务端,可以同时(并发)给多个客户端提供服务:

         我们需要在服务端开启多线程,只要有一个客户端连接到服务端,那么这是服务端内部就应该开启一个线程,为这个客户端服务,然后服务端继续等待下一个客户端的连接,只要有客户端连接到服务端,服务端就需要开启线程为当前连接到的这个客户端进行服务。

开启线程:直接new Thread 调用start,获取使用线程池都可以完成。

线程的任务:在服务端获取到客户端对象之后,后续的所有操作,都是基于当前这个客户端而进行,那么当前这些操作都属于线程的任务。

服务端

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.io.OutputStreamWriter;

import java.io.PrintWriter;

import java.net.ServerSocket;

import java.net.Socket;

import java.util.ArrayList;

import java.util.List;
//聊天室服务器端

public class Server {



//存放所有链接上当前服务器的客户端

private List<Socket> clientSockets=new ArrayList<Socket>();





public Server()

{



try {

//1.创建服务器端socket

ServerSocket serverSocket=new ServerSocket(9999);



while(true)

{

//2.接收客户端的socket

Socket socket= serverSocket.accept();



//3.存入集合中

this.clientSockets.add(socket);



//4.开一个线程处理客户端发送过来的消息

ReceiveThread thread=new ReceiveThread(socket);



thread.start();

}





} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}



}



//创建一个线程 接收客户端的socket

class ReceiveThread extends Thread

{

private Socket currentSocket;



public ReceiveThread(Socket socket)

{

this.currentSocket=socket;

}

public void run()

{



try {



//获得当前客户端中拿到的消息

InputStream is= this.currentSocket.getInputStream();

//获得输入流

BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(is));



String msg=null;



while((msg=bufferedReader.readLine())!=null)

{

//群发给所有的客户端

for(Socket socket :clientSockets)

{

PrintWriter pw =new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));



pw.println(msg);



pw.flush(); //发送到客户端



//不要关闭输出流 ftp协议中 规定 如果关闭当前socket输出流 则意味着对应的socket关闭

}





}



} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}



}



}

}

客户端

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;


public class Login extends JFrame{

private JLabel unameJLabel;

private JLabel pwdJLabel;

private JTextField unameJTextField;

private JTextField pwdJTextField;

private JButton loginJButton;

private JButton cancelJButton;

public Login()
{
super("IT全明星聊天室");

this.unameJLabel= new JLabel("用户名:");

this.pwdJLabel=new JLabel("密码:");

this.unameJTextField=new JTextField();

this.pwdJTextField=new JTextField();

this.loginJButton=new JButton("登录");

this.cancelJButton=new JButton("取消");

this.setSize(300,200);

this.setLayout(new GridLayout(3,2));

this.add(unameJLabel);

this.add(unameJTextField);

this.add(pwdJLabel);

this.add(pwdJTextField);

this.add(loginJButton);

this.add(cancelJButton);

//给按钮做监听事件
MyEvent myEvent=new MyEvent();
this.loginJButton.addActionListener(myEvent);


this.setLocationRelativeTo(null);

this.setVisible(true);




}

//监听单击事件
class MyEvent implements ActionListener
{

@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub

//1.获得用户名

String loginUname=unameJTextField.getText();


try {
//2.创建socket链接服务器端
Socket socket=new Socket("127.0.0.1", 9999);

//3.跳转到聊天室页面
new Client(socket,loginUname);

//4.当前登录窗口可以关闭
dispose();


} catch (UnknownHostException e) {
// TODO Auto-generated catch block
JOptionPane.showMessageDialog(null,"找不到服务器");
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block

网络通信之多人聊天室_服务端_02

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;


public class Client extends JFrame {

private JScrollPane topPanel; //滚动面板 用来放消息列表

private JPanel bottomPanel; //发送消息的面板

private JTextArea msgList; //存放消息列表 不可编辑

private JTextField msgText; //写消息的文本框

private JButton sendButton; //发送按钮

private Socket socket;

private String uname;


public Client(Socket socket,String uname)
{
super(uname);

this.socket=socket;
this.uname=uname;


//创建组件对象
this.topPanel=new JScrollPane();
this.bottomPanel=new JPanel();
this.msgList=new JTextArea();
this.msgText=new JTextField();
this.sendButton=new JButton("发送");

//设置属性 (绝对布局)
this.topPanel.setLayout(null);
this.bottomPanel.setLayout(null);

this.topPanel.setBounds(0, 0, 1000, 500);
this.msgList.setBounds(30,30,940,440);
this.bottomPanel.setBounds(0, 500, 1000, 100);
this.msgText.setBounds(30, 510, 700, 80);
this.sendButton.setBounds(750, 510, 200, 80);

//添加组件到窗口中
this.topPanel.add(msgList);
this.bottomPanel.add(msgText);
this.bottomPanel.add(sendButton);

this.add(topPanel);
this.add(bottomPanel);

//设置窗口属性
this.setSize(1000,600);
this.setLocationRelativeTo(null);
this.setVisible(true);

//开启一个线程 接收服务器端发回的消息
ReceiveThread receiveThread=new ReceiveThread();
receiveThread.start();

//对发送按钮做监听器
MyEvent myEvent=new MyEvent();
this.sendButton.addActionListener(myEvent);

}

class MyEvent implements ActionListener
{

@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub

//1.获得文本框的消息内容
String msg= msgText.getText();

//格式化日期
SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd");

String time=simpleDateFormat.format(new Date());

msg=time+uname+"说:"+msg;

//2.发送到服务器端
try {
PrintWriter pw=new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));

pw.println(msg);

pw.flush(); //不能关 socket中的输出流

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


}

}

//创建接收从服务器端返回的消息 的线程类
class ReceiveThread extends Thread{

public void run()
{
BufferedReader bufferedReader;
try {
//从服务器端读消息进来
bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));

String msg=null;

while((msg=bufferedReader.readLine())!=null)
{
msgList.append(msg+"\n");

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


}

}




}

网络通信之多人聊天室_客户端_03

  更多了解

​​https://edu.51cto.com/lecturer/14175030.html​​


网友评论