局域网聊天程序 java MySQL_java 基于TCP/IP协议的局域网聊天小程序
发布日期:2021-06-24 11:11:25 浏览次数:3 分类:技术文章

本文共 25072 字,大约阅读时间需要 83 分钟。

有6个模块

1.用户登录

2.两两私聊

3.群发消息

4.退出登录

5.关闭服务器

6.文件传输

一、用户登录

客户端:

1、发送登录信息:LOGIN|Username

处理USERLISTS命令:所有在线用户的用户名

2、处理新上线用户信息:ADD|username

服务器端:

1、得到所有在线用户信息名称,发回给客户端:USERLISTS|user1_user2_user3

2、将当前登录的Socket信息放入Arraylist中

3、将当前登录用户的信息(用户名),发送给已经在线的其他用户:ADD|userName

二、两两私聊

客户端:

1、选择用户

2、组织一个交互协议,发送到服务器:MSG|SenderName|RecName|MSGInfo

3、接收服务器转发回的消息

服务器端:

1、通过RecName用户名查找,找到目标SocketChat

2、向目标对象发送消息:MSG|SenderName|MSGInfo

三、群聊

MSG|Sendername|ALL|MSGInfo

四、用户退出连接

客户端:

1、向服务器发送下线消息:OFFLINE|username

2、关闭ClientChat,清空在线用户列表

3、处理下线用户信息:DEL|username

删除用户列表中的username

服务器端:

1、处理OFFLINE

2、向所有的其他在线用户发送用户下线消息:DEL|username

3、清除ArrayList中的当前用户信息(socketChat)

五、服务器关闭

客户端:

1、处理CLOSE命令:界面显示服务器关闭

2、关闭ClientChat

3、清空在线用户列表

服务器端:

1、向所有在线用户发送关闭服务器的信息:CLOSE

2、遍历Arraylist将其中的每一个SocketChat关闭

3、ArrayList要清空

4、关闭SokcetListener

5、关闭ServerSocket

六、文件传输

客户端:

准备工作:1,2,3

//1从本地选中一个文件,获取其文件相关信息(文件名,文件长度)

//2创建文件传输的服务器,与服务器接通

//3组织文件传输交互协议进行传输

//FILETRANS|sendername|recname|文件名|文件长度|IP|Port

处理服务器转发的内容,处理该内容确认是接收还是拒收,如果接收,建立连接通道接收文件(即开启fileRec线程)

如果拒收,组织拒收交互协议(FILECANCEL|拒收者|被拒收者)发送给服务器

服务器端:

接收发来的消息串,提取发送者+接收者+发送内容+传送文件的IP和Port 进行转发

服务器收到交互协议:FILECANCEL|拒收者|被拒收者 重新组织交互协议FILECANCELReturn|拒收者 要通知被拒收者,被拒收的消息

群发的流程图比较简单就没有画

1dcea73bf2fc563d5e5350c1212c63e4.png

3bcc91fe3d7a1b77f278d62b4d72ab7f.png

4994966342c44bd2f45092a725394200.png

六、文件传输

cb95b01e8c9901109c36a5b9948c2b28.png

以下代码只需修改以下IP地址和端口号即可运行,后期准备对发送消息的内容进行加密用Base64加密方法加密

客户端代码:

packagerjxy.lkl.Client;import java.io.*;import java.net.*;public class ClientChat extendsThread {

Socket socket;

BufferedReader br= null;

PrintWriter pw= null;

String UserName;publicClientChat(Socket socket, String userName) {this.socket =socket;

UserName=userName;try{

br= new BufferedReader(newInputStreamReader(socket.getInputStream(),"UTF-8"));

pw= new PrintWriter(new BufferedWriter(newOutputStreamWriter(

socket.getOutputStream(),"UTF-8")));

}catch(Exception e) {

e.printStackTrace();

}//约定一个登录的交互协议Login|username

sendMSG("Login|"+UserName);

}public voidsendMSG(String str){

pw.println(str);

pw.flush();

}//断开socket连接

public voidcloseChat(){try{if(socket!=null) socket.close();

}catch(Exception e) {

e.printStackTrace();

}

}//处理服务器发过来的在线用户List ,交互协议为:USERLISTS|user1_user2_user3

public voidrun() {try{

String str= "";while((str = br.readLine())!=null){

System.out.println("---"+str+"---");

String comms[]= str.split("[|]");if(comms[0].equals("USERLISTS")){

String users[]= comms[1].split("_");

ClientMG.getClientMG().addItems(users);

}else if(comms[0].equals("ADD")){

ClientMG.getClientMG().addItem(comms[1]);

}else if(comms[0].equals("MsgReturn")){//"MsgReturn|"+sender+"|"+msg

String sender = comms[1];

String msg= comms[2];

ClientMG.getClientMG().setLog("【"+sender+"】:");

ClientMG.getClientMG().setLog(msg);

}else if(comms[0].equals("DEL")){//交互协议为:"DEL|"+UserName

String sUser = comms[1];

ClientMG.getClientMG().removeItem(sUser);

ClientMG.getClientMG().setLog(sUser+"已下线");

}else if(comms[0].equals("CLOSE")){

ClientMG.getClientMG().setLog("服务器已关闭");//关闭ClientChat

ClientMG.getClientMG().getClientChat().closeChat();//清空在线用户列表

ClientMG.getClientMG().clearItems();

}else if(comms[0].equals("FILETRANS")){//"FILETRANS|"+sender+"|"+sFname+"|"+finfo.length()+"|"+IP+"|"+Port

String sender = comms[1];

String fileName= comms[2];int filelen = Integer.parseInt(comms[3]);

String sIP= comms[4];int port = Integer.parseInt(comms[5]);//调用ClientMG中的接收文件的方法

ClientMG.getClientMG().recFile(sender, fileName, filelen, sIP, port);

}else if(comms[0].equals("FILECANCEL")){

ClientMG.getClientMG().cancelFileTrans();

}else if (comms[0].equals("FILECANCELReturn")){//FILECANCELReturn|拒收者A

ClientMG.getClientMG().setLog(comms[1]+"取消了传输。。。");

}

}

}catch(Exception e) {

e.printStackTrace();

}finally{try{if (br != null)

br.close();if (pw != null)

pw.close();if (socket != null)

socket.close();

}catch(Exception e2) {

e2.printStackTrace();

}

}

}

}

packagerjxy.lkl.Client;importjava.awt.BorderLayout;public class ClientForm extendsJFrame {privateJPanel contentPane;publicJPanel panel;publicJLabel lblIp;publicJTextField txtIP;publicJLabel label_1;publicJTextField txtPort;publicJButton btnLogin;publicJButton btnExit;publicJPanel panel_1;publicJButton btnSend;

Socket socket;

BufferedReader br=null;

PrintWriter pw=null;publicJScrollPane scrollPane;publicJTextArea txtLog;publicJScrollPane scrollPane_1;publicJTextArea txtSend;publicJLabel label;publicJTextField txtUser;publicJScrollPane scrollPane_2;publicJList lOnlines;

DefaultListModel items=new DefaultListModel();publicJButton sendToAll;publicJButton FileTranbutton;publicJProgressBar FileprogressBar;/*** Launch the application.*/

public static voidmain(String[] args) {

EventQueue.invokeLater(newRunnable() {public voidrun() {try{

ClientForm frame= newClientForm();

frame.setVisible(true);

ClientMG.getClientMG().setClientForm(frame);

}catch(Exception e) {

e.printStackTrace();

}

}

});

}/*** Create the frame.*/

publicClientForm() {

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

setBounds(100, 100, 513, 583);

contentPane= newJPanel();

contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));

setContentPane(contentPane);

contentPane.setLayout(null);

panel= newJPanel();

panel.setLayout(null);

panel.setBorder(new TitledBorder(UIManager.getBorder("TitledBorder.border"), "\u767B\u5F55\u4FE1\u606F", TitledBorder.LEADING, TitledBorder.TOP, null, null));

panel.setBounds(11, 10, 476, 64);

contentPane.add(panel);

lblIp= new JLabel("IP:");

lblIp.setHorizontalAlignment(SwingConstants.RIGHT);

lblIp.setBounds(10, 19, 35, 31);

panel.add(lblIp);

txtIP= newJTextField();

txtIP.setText("10.12.50.10");

txtIP.setColumns(10);

txtIP.setBounds(55, 22, 97, 24);

panel.add(txtIP);

label_1= new JLabel("\u7AEF\u53E3:");

label_1.setHorizontalAlignment(SwingConstants.RIGHT);

label_1.setBounds(154, 19, 35, 31);

panel.add(label_1);

txtPort= newJTextField();

txtPort.setText("8899");

txtPort.setColumns(10);

txtPort.setBounds(190, 21, 35, 26);

panel.add(txtPort);

btnLogin= new JButton("\u767B\u5F55");

btnLogin.addActionListener(newBtnLoginActionListener());

btnLogin.setBounds(337, 22, 65, 25);

panel.add(btnLogin);

btnExit= new JButton("\u9000\u51FA");

btnExit.addActionListener(newBtnExitActionListener());

btnExit.setBounds(401, 22, 65, 25);

panel.add(btnExit);

label= new JLabel("\u7528\u6237\u540D:");

label.setHorizontalAlignment(SwingConstants.RIGHT);

label.setBounds(228, 19, 50, 31);

panel.add(label);

txtUser= newJTextField();

txtUser.setText("visiter");

txtUser.setColumns(10);

txtUser.setBounds(281, 22, 50, 26);

panel.add(txtUser);

panel_1= newJPanel();

panel_1.setLayout(null);

panel_1.setBorder(new TitledBorder(new LineBorder(new Color(184, 207, 229)), "\u64CD\u4F5C", TitledBorder.LEADING, TitledBorder.TOP, null, null));

panel_1.setBounds(10, 414, 477, 121);

contentPane.add(panel_1);

btnSend= new JButton("\u53D1\u9001\u6D88\u606F");

btnSend.addActionListener(newBtnSendActionListener());

btnSend.setBounds(357, 82, 110, 23);

panel_1.add(btnSend);

scrollPane_1= newJScrollPane();

scrollPane_1.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);

scrollPane_1.setBounds(10, 24, 457, 48);

panel_1.add(scrollPane_1);

txtSend= newJTextArea();

scrollPane_1.setViewportView(txtSend);

sendToAll= new JButton("\u7FA4\u53D1\u6D88\u606F");

sendToAll.addActionListener(newButtonActionListener());

sendToAll.setBounds(254, 82, 93, 23);

panel_1.add(sendToAll);

FileTranbutton= new JButton("\u4F20\u8F93\u6587\u4EF6");

FileTranbutton.addActionListener(newButtonActionListener_1());

FileTranbutton.setBounds(10, 82, 81, 23);

panel_1.add(FileTranbutton);

FileprogressBar= newJProgressBar();

FileprogressBar.setBounds(98, 92, 146, 8);

panel_1.add(FileprogressBar);

scrollPane= newJScrollPane();

scrollPane.setBorder(new TitledBorder(null, "\u804A\u5929\u8BB0\u5F55", TitledBorder.LEADING, TitledBorder.TOP, null, null));

scrollPane.setBounds(11, 84, 309, 332);

contentPane.add(scrollPane);

txtLog= newJTextArea();

scrollPane.setViewportView(txtLog);

scrollPane_2= newJScrollPane();

scrollPane_2.setBorder(new TitledBorder(null, "\u5728\u7EBF\u7528\u6237", TitledBorder.LEADING, TitledBorder.TOP, null, null));

scrollPane_2.setBounds(323, 83, 164, 332);

contentPane.add(scrollPane_2);

lOnlines= newJList(items);

scrollPane_2.setViewportView(lOnlines);

}//登录

private class BtnLoginActionListener implementsActionListener {public voidactionPerformed(ActionEvent arg0) {

String ip=txtIP.getText().trim();int port =Integer.parseInt(txtPort.getText().trim());

String socketname=txtUser.getText().trim();

ClientMG.getClientMG().connect(ip, port, socketname);

}

}//发送信息

private class BtnSendActionListener implementsActionListener {public voidactionPerformed(ActionEvent arg0) {//选中要聊天的用户

String sendUsername = null;if(lOnlines.getSelectedIndex()>=0){//得到用户选择的名称

String targetUsername =lOnlines.getSelectedValue().toString();

System.out.println(targetUsername);//发送者的名称

sendUsername =txtUser.getText().trim();//消息体

String sMSG =txtSend.getText();//交互协议 "MSG|"+sendUsername+"|"+targetUsername+"|"+sMSG//包装后的消息发送出去

String strSend = "MSG|"+sendUsername+"|"+targetUsername+"|"+sMSG;

System.out.println(strSend);

ClientMG.getClientMG().getClientChat().sendMSG(strSend);

ClientMG.getClientMG().setLog("I send To "+targetUsername+":");

ClientMG.getClientMG().setLog(sMSG);//清空发送消息框

txtSend.setText("");

}

}

}//推出操作

private class BtnExitActionListener implementsActionListener {public voidactionPerformed(ActionEvent arg0) {//组织推出交互协议"OFFLINE|"+username

String sendMSG = "OFFLINE|"+txtUser.getText().trim();

ClientMG.getClientMG().getClientChat().sendMSG(sendMSG);//断开与服务器的socket连接

ClientMG.getClientMG().getClientChat().closeChat();

ClientMG.getClientMG().clearItems();//清空列表

}

}private class ButtonActionListener implementsActionListener {public voidactionPerformed(ActionEvent e) {//发送者的名称

String sendUsername =txtUser.getText().trim();//消息体

String sMSG =txtSend.getText();//交互协议 "MSG|"+sendUsername+"|"+targetUsername+"|"+sMSG//包装后的消息发送出去

String strSend = "MSG|"+sendUsername+"|ALL|"+sMSG;

System.out.println(strSend);//协议为:"MSG|"+sendUsername+"|ALL|"+msg

ClientMG.getClientMG().getClientChat().sendMSG(strSend);

txtSend.setText("");

}

}//传输文件

private class ButtonActionListener_1 implementsActionListener {public voidactionPerformed(ActionEvent e) {//1从本地选中一个文件,获取其文件相关信息(文件名,文件长度)//2创建文件传输的服务器,与服务器接通//3组织文件传输交互协议进行传输//FILETRANS|sendername|recname|文件名|文件长度|IP|Port

File finfo= null;//用于文件选择的对象jFileChooser

JFileChooser jFileChooser = newJFileChooser();int result = jFileChooser.showOpenDialog(null);if(result==JFileChooser.APPROVE_OPTION){

finfo= newFile(jFileChooser.getSelectedFile().getAbsolutePath());

String sFname=finfo.getName();//在用户列表中选择目标用户

if(lOnlines.getSelectedIndex()!=-1){

String sTarget= lOnlines.getSelectedValue().toString();//得到目标用户

String sender =txtUser.getText().trim();//得到新开服务器的IP+Port

String IPandPort =ClientMG.getClientMG().CreateFileTranServer(finfo);//组织交互协议串,然后发送 FILETRANS+发送者+目标用户+文件名+文件的长度+IP和端口号

String strSend = "FILETRANS|"+sender+"|"+sTarget+"|"+sFname+"|"+finfo.length()+"|"+IPandPort;

ClientMG.getClientMG().getClientChat().sendMSG(strSend);

}

}

}

}

}

packagerjxy.lkl.Client;importjava.io.File;importjava.io.IOException;importjava.net.InetAddress;importjava.net.ServerSocket;importjava.net.Socket;importjava.net.UnknownHostException;importjavax.swing.JOptionPane;public classClientMG {//实现管理类的单例化

private static final ClientMG clientMG = newClientMG();publicClientMG() {

}public staticClientMG getClientMG(){returnclientMG;

}//操作图形化界面

ClientForm cWin;

ClientChat cChat;public voidsetClientForm(ClientForm cf){

cWin=cf;

}//设置界面中的消息记录

public voidsetLog(String str){

cWin.txtLog.append(str+"\r\n");

}publicClientChat getClientChat(){returncChat;

}//新上线的用户添加到JList中

public voidaddItem(String username){

cWin.items.addElement(username);

}public voidaddItems(String [] sItems){for(String username : sItems) {

addItem(username);

}

}//一旦断开连接,清空JList中的用户//清空单个

public voidremoveItem(String str){

cWin.items.removeElement(str);

}//清空所有

public voidclearItems(){

cWin.items.clear();

}public void connect(String IP,intport,String Username){try{

Socket socket= newSocket(IP,port);

ClientMG.getClientMG().setLog("已连接到服务器 ");

cChat= newClientChat(socket,Username);

cChat.start();

}catch(Exception e) {

e.printStackTrace();

}

}

FileListener filelistener;//创建文件传输的服务器

publicString CreateFileTranServer(File file){try{

ServerSocket server= new ServerSocket(8881);

String IP=InetAddress.getLocalHost().getHostAddress();

filelistener= newFileListener(server,file);

filelistener.start();return IP+"|"+8881;

}catch(Exception e) {

e.printStackTrace();

}return "";

}//接收文件

public void recFile(String sender,String fName,int len,String IP,intport){//文件名|文件长度|IP|Port//4判断是否要接收? JOptionPane->confirm//5同意接收,连接服务器进行文件传输//6拒绝接收,向服务器发回拒接接收的消息:FILECANCEL|sendername|recname

JOptionPane msg= newJOptionPane();int result = msg.showConfirmDialog(null, sender+"发送文件【"+fName+"】,\r\n是否接收?", "文件传输确认", JOptionPane.YES_NO_OPTION);if(result ==JOptionPane.YES_NO_OPTION){//确认接收

try{

Socket socket= newSocket(IP,port);newfileRec(socket, fName, len).start();

}catch(Exception e) {

e.printStackTrace();

}

}else{//如果拒收 FILECANCEL|FromUser|toUser,sender给我发消息,某某某拒绝了,就通知sender,某某某拒绝了你的文件传输

String strSend = "FILECANCEL|"+this.getClientChat().UserName+"|"+sender;this.getClientChat().sendMSG(strSend);this.setLog("您已拒接了"+sender+"的文件传输");

}

}//对方取消文件传递

public voidcancelFileTrans(){

filelistener.cancelFileTrans();//this.setLog("对方取消了文件传输!!!");

}

}

packagerjxy.lkl.Client;import java.io.*;import java.net.*;public class FileListener extendsThread {

ServerSocket fserver;

File filetrans;publicFileListener(ServerSocket fserver, File filetrans) {this.fserver =fserver;this.filetrans =filetrans;

}//取消传输

public voidcancelFileTrans(){if(fserver!=null){try{

fserver.close();

}catch(Exception e) {

e.printStackTrace();

}

}

}public voidrun() {

Socket sfile= null;

DataInputStream dis= null;

DataOutputStream dos= null;try{

sfile=fserver.accept();

dis= new DataInputStream(newFileInputStream(filetrans));

dos= newDataOutputStream(sfile.getOutputStream());//有关进度条属性的设置

ClientMG.getClientMG().cWin.FileprogressBar.setValue(0);

ClientMG.getClientMG().cWin.FileprogressBar.setVisible(true);

ClientMG.getClientMG().cWin.FileprogressBar.setMaximum((int)filetrans.length());byte[] buff = new byte[1024];int iread = 0;int len =0;while((iread=dis.read(buff, 0, 1024))!=-1){

dos.write(buff,0, iread); //写文件是,是根据读出的大小进行写入的

len +=iread;

dos.flush();//写入流的同时,设置进度条的进度

ClientMG.getClientMG().cWin.FileprogressBar.setValue(len);

}

ClientMG.getClientMG().setLog("文件传输完毕!");

}catch(Exception e) {

e.printStackTrace();

}finally{try{

dos.close();

dis.close();if(sfile!=null){sfile.close();}if(fserver!=null){fserver.close();}

}catch(Exception e) {

e.printStackTrace();

}

}

}

}

packagerjxy.lkl.Client;importjava.io.DataInputStream;importjava.io.DataOutputStream;importjava.io.FileNotFoundException;importjava.io.FileOutputStream;importjava.io.IOException;import java.net.*;public class fileRec extendsThread{

Socket socket;

String sRecFilePath="D:\\";

String fileName;intfileLen;public fileRec(Socket socket, String fileName, intfileLen) {this.socket =socket;this.fileName =fileName;this.fileLen =fileLen;

}public voidrun() {

DataInputStream dis= null;

DataOutputStream dos= null;//设置进度条属性

ClientMG.getClientMG().cWin.FileprogressBar.setValue(0);

ClientMG.getClientMG().cWin.FileprogressBar.setVisible(true);

ClientMG.getClientMG().cWin.FileprogressBar.setMaximum(fileLen);try{

dis= newDataInputStream(socket.getInputStream());

dos= new DataOutputStream(new FileOutputStream(sRecFilePath+fileName));byte[] buff = new byte[1024];int iread = 0;int len = 0;while((iread=dis.read(buff, 0, 1024))!=-1){

dos.write(buff,0, iread);

len+=iread;

ClientMG.getClientMG().cWin.FileprogressBar.setValue(len);

dos.flush();

}

ClientMG.getClientMG().setLog("文件接收完毕!");

}catch(Exception e) {

e.printStackTrace();

}finally{try{

dis.close();

dos.close();if(socket!=null){ socket.close();}

}catch(Exception e) {

e.printStackTrace();

}

}

}

}

服务器端代码:

packagerjxy.lkl.Server;importjava.awt.BorderLayout;public class ServerForm extendsJFrame {privateJPanel contentPane;publicJPanel panel;publicJLabel label;publicJTextField txtPort;publicJButton btnStart;publicJButton btnStop;publicJScrollPane scrollPane;publicJTextArea txtLog;

ServerSocket server;

ServerListener listener;volatile booleanserverFlag;/*** Launch the application.*/

public static voidmain(String[] args) {

EventQueue.invokeLater(newRunnable() {public voidrun() {try{

ServerForm frame= newServerForm();

frame.setVisible(true);

SocketMG.getsocketMG().setServerForm(frame);//窗体对象传入SocketMG中

} catch(Exception e) {

e.printStackTrace();

}

}

});

}/*** Create the frame.*/

publicServerForm() {

setResizable(false);

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

setBounds(100, 100, 422, 520);

contentPane= newJPanel();

contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));

setContentPane(contentPane);

contentPane.setLayout(null);

panel= newJPanel();

panel.setBorder(new TitledBorder(null, "\u914D\u7F6E\u4FE1\u606F", TitledBorder.LEADING, TitledBorder.TOP, null, null));

panel.setBounds(0, 0, 406, 66);

contentPane.add(panel);

panel.setLayout(null);

label= new JLabel("\u7AEF\u53E3\uFF1A");

label.setBounds(10, 29, 54, 15);

panel.add(label);

txtPort= newJTextField();

txtPort.setText("8899");

txtPort.setBounds(46, 21, 66, 30);

panel.add(txtPort);

txtPort.setColumns(10);

btnStart= new JButton("\u5F00\u59CB\u670D\u52A1");

btnStart.addActionListener(newBtnStartActionListener());

btnStart.setBounds(129, 21, 98, 31);

panel.add(btnStart);

btnStop= new JButton("\u505C\u6B62\u670D\u52A1");

btnStop.addActionListener(newBtnStopActionListener());

btnStop.setBounds(253, 21, 98, 31);

panel.add(btnStop);

scrollPane= newJScrollPane();

scrollPane.setBorder(new TitledBorder(null, "\u6D88\u606F\u8BB0\u5F55", TitledBorder.LEADING, TitledBorder.TOP, null, null));

scrollPane.setBounds(0, 76, 406, 406);

contentPane.add(scrollPane);

txtLog= newJTextArea();

scrollPane.setViewportView(txtLog);

}//启动Socket服务

private class BtnStartActionListener implementsActionListener {public voidactionPerformed(ActionEvent arg0) {int port =Integer.parseInt(txtPort.getText().trim());try{

server= newServerSocket(port);

listener= newServerListener(server);

listener.start();

SocketMG.getsocketMG().setLog("服务已开启");

}catch(Exception e) {

e.printStackTrace();

}

}

}//停止服务

private class BtnStopActionListener implementsActionListener {public voidactionPerformed(ActionEvent arg0) {

SocketMG.getsocketMG().setLog("服务器已关闭");//通知所有在线用户服务器关闭消息 交互协议为:"CLOSE|"

SocketMG.getsocketMG().sendCloseMSGToAll();//把OnlineUsers集合中的每一个SocketChat关闭

SocketMG.getsocketMG().closeALLSocket();//ArrayList清空

SocketMG.getsocketMG().clearList();//关闭ServerSocket

listener.stopListener();try{if (server != null) {

serverFlag= false;

server.close();

}

}catch(Exception e2) {//TODO: handle exception

}

}

}

}

packagerjxy.lkl.Server;importjava.io.IOException;import java.net.*;public class ServerListener extendsThread {

ServerSocket server;volatile booleanserverFlag;publicServerListener(ServerSocket server) {this.server =server;

serverFlag= true;

}//停止监听

public voidstopListener(){

serverFlag= false;

}public voidrun() {while(serverFlag){

Socket s= null;try{

s=server.accept();newSocketChat(s).start();

SocketMG.getsocketMG().setLog(s+"已登录");

}catch(Exception e) {

e.printStackTrace();

}

}

}

}

packagerjxy.lkl.Server;import java.net.*;import java.io.*;public class SocketChat extendsThread {

Socket socket;

BufferedReader br=null;

PrintWriter pw= null;

String UserName;publicSocketChat(Socket socket) {this.socket =socket;try{

br= new BufferedReader(newInputStreamReader(socket.getInputStream(),"UTF-8"));

pw= new PrintWriter(new BufferedWriter(newOutputStreamWriter(

socket.getOutputStream(),"UTF-8")));

}catch(Exception e) {

e.printStackTrace();

}

}public voidsendMSG(String str){

pw.println(str);

pw.flush();

}//关闭SocketChat

public voidcloseChat(){try{if (socket != null)

socket.close();

}catch(Exception e) {

e.printStackTrace();

}

}public voidrun() {try{

String str= "";while((str = br.readLine())!=null){

String comm[]= str.split("[|]");if(comm[0].equals("Login")){//读取客户端发过来的用户名

String cUsername = comm[1];//赋给服务器端的UserName

UserName =cUsername;//①得到所有在线用户发给客户端

SocketMG.getsocketMG().sendOnlineUsers(this);//②将当期的socket信息存放在OnLineUsers数组中

SocketMG.getsocketMG().addList(this);//③把当前用户信息发送给在线用户

SocketMG.getsocketMG().sendNewUsertoAll(this);

}else if(comm[0].equals("MSG")){//交互协议 "MSG|"+sendUsername+"|"+targetUsername+"|"+sMSG//取出协议串中的内容

String sender = comm[1];

String receiver= comm[2];

String msg= comm[3];

System.out.println("发送者:"+sender+"---接收者:"+receiver+"---消息体:"+msg);if(receiver.equals("ALL")){//"MSG|"+sendUsername+"|ALL|"+msg

String strmsg = "MsgReturn|"+sender+"|"+msg;

SocketMG.getsocketMG().sendMSGToALL(strmsg,this);

SocketMG.getsocketMG().setLog(sender+"发消息给所有人"+"内容为:"+msg);

}else{//查询在线集合,如果接收对象则返回这个SocketChat对象

SocketChat sc =SocketMG.getsocketMG().getSocketChatByName(receiver);

System.out.println("选中的用户的信息:"+sc);if(!(sc==null)){

String strmsg= "MsgReturn"+"|"+sender+"|"+msg; //重新组织交换协议

System.out.println(strmsg);

SocketMG.getsocketMG().sendMSGToSocket(strmsg, sc);

SocketMG.getsocketMG().setLog(sender+"发送给"+sc+"的消息是:"+msg);

}

}

}else if(comm[0].equals("OFFLINE")){//用户下线的交互协议:"OFFLINE|"+username//向其他用户发送该用户下线的消息

SocketMG.getsocketMG().sendOffLineMSGToAll(this);//移除List中已经下线用户的信息

SocketMG.getsocketMG().removeList(this);

SocketMG.getsocketMG().setLog(comm[1]+"下线了");

}else if(comm[0].equals("FILETRANS")){//"FILETRANS|"+sender+"|"+sTarget+"|"+sFname+"|"+finfo.length()+"|"+IPandPort

String sender = comm[1];

SocketChat sTarget= SocketMG.getsocketMG().getSocketChatByName(comm[2]);//sFname+"|"+finfo.length()+"|"+IPandPort

String strSend = comm[3]+"|"+comm[4]+"|"+comm[5]+"|"+comm[6];//调用文件发送函数

SocketMG.getsocketMG().sendFileTrans(sender, sTarget, strSend);

SocketMG.getsocketMG().setLog(sender+"发送了"+strSend+"给"+sTarget);

}else if(comm[0].equals("FILECANCEL")){//FILECANCEL|拒收者(A)|被拒收者(B)//得到被拒收者

String A = comm[1];

SocketChat sc= SocketMG.getsocketMG().getSocketChatByName(comm[2]);//重新组织交互协议//FILECANCELReturn|拒收者A

String strSend = "FILECANCELReturn|"+A;

SocketMG.getsocketMG().setLog(A+"拒收了"+comm[2]+"传输的文件");

sc.sendMSG(strSend);

}

}

}catch(Exception e) {

e.printStackTrace();

}finally{try{if (br != null)

br.close();if (pw != null)

pw.close();if (socket != null)

socket.close();

}catch(Exception e2) {

e2.printStackTrace();

}

}

}

}

packagerjxy.lkl.Server;importjava.util.ArrayList;public classSocketMG {//实现管理类的单例化

private static final SocketMG socketMG=newSocketMG();privateSocketMG(){}public staticSocketMG getsocketMG(){returnsocketMG;

}

SocketChat sChat;//操作图形界面

ServerForm sWin;public voidsetServerForm(ServerForm s){

sWin=s;

}//设置界面中的消息记录

public voidsetLog(String str){

sWin.txtLog.append(str+"\r\n");

}//存储socket信息的集合

private ArrayList OnLineUsers = new ArrayList();//把新用户添加到集合中

public synchronized voidaddList(SocketChat sChat){

OnLineUsers.add(sChat);

}//得到所有用户在线信息名称,发回给客户端

public voidsendOnlineUsers(SocketChat sc){//发送所有用户信息的协议:USERLISTS|user1_user2_user3

if(OnLineUsers.size()>0){

String str= "";for (int i = 0; i < OnLineUsers.size(); i++) {

SocketChat sChat=OnLineUsers.get(i);

str+= sChat.UserName+"_";

}

sc.sendMSG("USERLISTS|"+str);

}

}//新上线的用户发送给所有在线用户 ADD|用户名

public voidsendNewUsertoAll(SocketChat sc){for (int i = 0; i < OnLineUsers.size(); i++) {

SocketChat socketChat=OnLineUsers.get(i);//新上线用户这个消息不发给自己,发给其他用户,让其他用户知道该你上线了

if(!socketChat.equals(sc)){

socketChat.sendMSG("ADD|"+sc.UserName);

}

}

}//通过用户名查找SocketChat对象

publicSocketChat getSocketChatByName(String name){for (int i = 0; i < OnLineUsers.size(); i++) {

SocketChat sChat=OnLineUsers.get(i);//此处曾出现过错误,形式为:sChat.equals(name)

if(sChat.UserName.equals(name)){returnsChat;

}

}return null;

}//向目标对象发送消息

public voidsendMSGToSocket(String str,SocketChat sc){

System.out.println("2222222222222"+str);

sc.sendMSG(str);

}//发送消息出自己以外的所有人

public voidsendMSGToALL(String str,SocketChat sc){for (int i = 0; i < OnLineUsers.size(); i++) {//写程序的时候遇到的问题:SocketChat sChat = OnLineUsers.get(i);//造成了与类成员变量重名,消息只发给自己

SocketChat socketChat =OnLineUsers.get(i);//if(!socketChat.equals(sc)){//socketChat.sendMSG(str);//}

socketChat.sendMSG(str);

}

}//向其他用户发送下线用户下线的通知

public voidsendOffLineMSGToAll(SocketChat sc){for (int i = 0; i < OnLineUsers.size(); i++) {

SocketChat socketChat=OnLineUsers.get(i);if(!socketChat.equals("sc")){

String str= "DEL|"+sc.UserName;

socketChat.sendMSG(str);

}

}

}//把当前下线的用户从OnLineUsers中清除

public synchronized voidremoveList(SocketChat sChat){//清除ArrayList中的当前用户信息(socketChat)

for (int i = 0; i < OnLineUsers.size(); i++) {

SocketChat schat=OnLineUsers.get(i);if(schat.equals(sChat)){

OnLineUsers.remove(sChat);break;

}

}

}//关闭服务器通知给所有在线用户

public voidsendCloseMSGToAll(){//组织交互协议为:"CLOSE|"

for (int i = 0; i < OnLineUsers.size(); i++) {

SocketChat socketchat=OnLineUsers.get(i);

socketchat.sendMSG("CLOSE|");

}

}//关闭OnlineUsers中的每一个SocketChat

public voidcloseALLSocket(){for (int i = 0; i < OnLineUsers.size(); i++) {

SocketChat socketchat=OnLineUsers.get(i);

socketchat.closeChat();

}

}//清空在线集合中的内容

public voidclearList(){

OnLineUsers.clear();

}//文件传输 发送者,接收者,内容

public voidsendFileTrans(String sender,SocketChat sTarget,String sMSG){

sTarget.sendMSG("FILETRANS|"+sender+"|"+sMSG);

}

}

转载地址:https://blog.csdn.net/weixin_32421193/article/details/113441866 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:r glm 中的p值_假设检验中的P值
下一篇:mysql多维模型_数据仓库数据库设计方法---关系模型和多维模型比较分析

发表评论

最新留言

感谢大佬
[***.8.128.20]2024年04月06日 05时59分25秒