聊天室私聊求思路`

chump345 2009-11-06 05:17:05
聊天室的公聊已经弄出来了`
但是私聊却无从下手`
用服务器端存取每个建立连接的客户只能得到对方的IP` 和连接的端口号` 存这些信息是用集合的HaspMap来存么?
公聊和私聊貌似可以通过在聊天信息前面加字符来区分`
但是我要选择和哪个用户进行私聊`该怎么和那个用户建立连接呢`
在服务器端也只能得到另一个用户的IP`和端口号`
我是自己一台机器实验` IP都相同` 端口号不同`
在swing里面` 都是自定义的名字`
和某人聊天不可能就要输对方的IP` 和他与服务器连接的端口号吧`
私聊的具体思路是怎样的呢` 求解答`
...全文
287 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
deathv1 2010-04-28
  • 打赏
  • 举报
回复
很好的思路,谢谢指点了
aaby167 2009-11-07
  • 打赏
  • 举报
回复
最关键的问题
用户名一定要是唯一的
不然不知道是和谁私聊
bawgiitx 2009-11-06
  • 打赏
  • 举报
回复
Socket 不就是了
chump345 2009-11-06
  • 打赏
  • 举报
回复
就没有TCP/IP的么?
bawgiitx 2009-11-06
  • 打赏
  • 举报
回复
刚刚好我写有,自己定义一个自己的CS协议不就行了http://download.csdn.net/source/1795293
py330316117 2009-11-06
  • 打赏
  • 举报
回复
private void receiveInfo(final ChatTree tree) {// 接收信息
if (buf.length > 0) {
String rText = new String(buf).replace("" + (char) 0, "");
String hostAddress = dp.getAddress().getHostAddress();
String info = dao.getUser(hostAddress).getName();
info = info + " (" + new Date().toLocaleString() + ")";
appendReceiveText(info, Color.BLUE);
appendReceiveText(rText + "\n", null);
}
}

class sendActionListener implements ActionListener {
public void actionPerformed(final ActionEvent e) {
String sendInfo = getSendInfo(); //获取信息发送文本
if (sendInfo == null)
return;
insertUserInfoToReceiveText(tree); //插入用户信息
appendReceiveText(sendInfo + "\n", null); //追加发送信息
byte[] tmpBuf = sendInfo.getBytes();
DatagramPacket tdp = null; //数据报
try {//使用数据报将消息使用1111端口发送到指定ip
tdp = new DatagramPacket(tmpBuf, tmpBuf.length,
new InetSocketAddress(ip, 1111));
ss.send(tdp);
} catch (SocketException e2) {
e2.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
JOptionPane.showMessageDialog(TelFrame.this, e1
.getMessage());
}
sendText.setText(null);
sendText.requestFocus();
if (messageMode.isSelected())
setState(ICONIFIED);
}
}

class toolbarActionListener implements ActionListener {
public void actionPerformed(final ActionEvent e) {
JOptionPane.showMessageDialog(TelFrame.this, "功能隐藏");
}
}

private final class TelFrameClosing extends WindowAdapter {
private final JTree tree;

private TelFrameClosing(JTree tree) {
this.tree = tree;
}

public void windowClosing(final WindowEvent e) {
tree.setSelectionPath(null);
TelFrame.this.setState(ICONIFIED);
TelFrame.this.dispose();
}
}

private class MessageButtonActionListener implements ActionListener {// 信史按钮
public void actionPerformed(final ActionEvent e) {
try {
Document doc = sendText.getDocument();
String sendInfo = doc.getText(0, doc.getLength());
if (sendInfo.equals("") || sendInfo == null) {
JOptionPane.showMessageDialog(TelFrame.this, "不能发送空信息。");
return;
}
insertUserInfoToReceiveText(tree);
appendReceiveText(sendInfo, null);
Resource.sendMessenger(user, sendInfo, frame);
sendText.setText(null);
sendText.requestFocus();
} catch (BadLocationException e1) {
e1.printStackTrace();
}
}
}
private class SendTextKeyListener extends KeyAdapter {
public void keyPressed(KeyEvent e) {
if (e.isControlDown() && e.getKeyCode() == 10)
sendButton.doClick();
else if (e.isShiftDown() && e.getKeyCode() == 10)
messageButton.doClick();
}
}
private class Button_1ActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
panel_3.setVisible(!panel_3.isVisible());
TelFrame.this.setVisible(true);
}
}

public JButton getSendButton() {
return sendButton;
}

public JTextPane getReceiveText() {
return receiveText;
}

public void setBufs(byte[] bufs) {
this.buf = bufs;
}

public String getSendInfo() {
String sendInfo = "";
Document doc = sendText.getDocument();
try {
sendInfo = doc.getText(0, doc.getLength());
} catch (BadLocationException e) {
e.printStackTrace();
}
if (sendInfo.equals("")) {
JOptionPane.showMessageDialog(TelFrame.this, "不能发送空信息。");
return null;
}
return sendInfo;
}

private void insertUserInfoToReceiveText(final ChatTree tree) {
String info = null;
try {
String hostAddress = InetAddress.getLocalHost().getHostAddress();
info = dao.getUser(hostAddress).getName();
} catch (UnknownHostException e1) {
e1.printStackTrace();
}
info = info + " (" + new Date().toLocaleString() + ")";
appendReceiveText(info, new Color(68, 184, 29));
}

public JTextPane getSendText() {
return sendText;
}

public void appendReceiveText(String sendInfo, Color color) {
Style style = receiveText.addStyle("title", null);
if (color != null) {
StyleConstants.setForeground(style, color);
} else {
StyleConstants.setForeground(style, Color.BLACK);
}
receiveText.setEditable(true);
receiveText.setCaretPosition(receiveText.getDocument().getLength());
receiveText.setCharacterAttributes(style, false);
receiveText.replaceSelection(sendInfo + "\n");
receiveText.setEditable(false);
}
}
py330316117 2009-11-06
  • 打赏
  • 举报
回复
代码有点长,自己慢慢研究吧
package com.myqq.frame;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.util.*;
import javax.swing.*;
import javax.swing.border.BevelBorder;
import javax.swing.text.*;
import com.myqq.MyQQ;
import com.myqq.dao.Dao;
import com.myqq.system.Resource;
import com.myqq.userList.ChatTree;
import com.myqq.userList.User;
public class TelFrame extends JFrame {
private Dao dao;
private User user;
private JTextPane receiveText = new JTextPane();
private JScrollPane scrollPane = new JScrollPane();
private JTextPane sendText = new JTextPane();
private JScrollPane scrollPane_1 = new JScrollPane();
private JSplitPane splitPane = new JSplitPane();
private JButton sendButton = new JButton();
private final JButton messageButton = new JButton();
private JPanel panel = new JPanel();
private final static Map<String, TelFrame> instance = new HashMap<String, TelFrame>();
private final JCheckBox messageMode = new JCheckBox();
private JToolBar toolBar = new JToolBar();
private JToggleButton toolFontButton = new JToggleButton();
private JButton toolFaceButton = new JButton();
private JButton button = new JButton();
private JButton button_3 = new JButton();
private final JButton button_1 = new JButton();
private final JPanel panel_5 = new JPanel();
private JPanel panel_2 = new JPanel();
private JPanel panel_1 = new JPanel();
private JLabel label = new JLabel();
private final JScrollPane scrollPane_2 = new JScrollPane();
private final JLabel label_1 = new JLabel();
private JPanel panel_3 = new JPanel();
private byte[] buf;
private DatagramSocket ss;
private String ip;
private DatagramPacket dp;
private TelFrame frame;
private ChatTree tree;
private int rightPanelWidth = 148;
public static synchronized TelFrame getInstance(DatagramSocket ssArg,
DatagramPacket dp, ChatTree treeArg) {
String tmpIp = dp.getAddress().getHostAddress();//获取用户地址
if (!instance.containsKey(tmpIp)) { //判断集合中是否存在该用户的窗体
TelFrame frame = new TelFrame(ssArg, dp, treeArg);//创建新窗体
instance.put(tmpIp, frame); //更新窗体集合
frame.receiveInfo(treeArg); //添加接受的信息
if (!frame.isVisible()) { //如果窗体用于隐藏状态
frame.setVisible(true);
}
frame.setState(JFrame.NORMAL);
frame.toFront();
return frame;
} else { //如果集合中包含该用户的窗体
TelFrame frame = instance.get(tmpIp); //从集合中获取窗体实例
frame.setBufs(dp.getData());
frame.receiveInfo(treeArg); //接受信息
if (!frame.isVisible()) {
frame.setVisible(true); //显示窗体
}
frame.setState(JFrame.NORMAL);
frame.toFront();
return frame;
}
}

public TelFrame(DatagramSocket ssArg, DatagramPacket dpArg,
final ChatTree treeArg) {
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
this.tree = treeArg;//获取用户列表对象
ip = dpArg.getAddress().getHostAddress();//获取用户IP
dao = Dao.getDao();//初始化Dao实例
user = dao.getUser(ip);//获取用户对象
frame = this; //获取窗体
ss = ssArg;//获取数据服务对象
dp = dpArg;//获取数据报
buf = dp.getData();//获取数据报中的数据
try {
setBounds(200, 100, 521, 424);//设置窗体的大小、位置
getContentPane().add(splitPane);//添加分割面板
splitPane.setDividerSize(2);//设置面板分隔线大小
splitPane.setResizeWeight(0.8);//定义面板竖向分割
splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
splitPane.setLeftComponent(scrollPane);
scrollPane.setViewportView(getReceiveText());
receiveText.setFont(new Font("宋体", Font.PLAIN, 12));
receiveText.setInheritsPopupMenu(true);
receiveText.setVerifyInputWhenFocusTarget(false);
receiveText.setDragEnabled(true);
receiveText.setMargin(new Insets(0, 0, 0, 0));
receiveText.setEditable(false);
getReceiveText().addComponentListener(new ComponentAdapter() {
public void componentResized(final ComponentEvent e) {
scrollPane.getVerticalScrollBar().setValue(
getReceiveText().getHeight());
}
});
getReceiveText().setDoubleBuffered(true);

splitPane.setRightComponent(panel_2);
panel_2.setLayout(new BorderLayout());

final FlowLayout flowLayout = new FlowLayout();
flowLayout.setHgap(4);
flowLayout.setAlignment(FlowLayout.LEFT);
flowLayout.setVgap(0);
panel_2.add(panel, BorderLayout.SOUTH);
final FlowLayout flowLayout_1 = new FlowLayout();
flowLayout_1.setVgap(3);
flowLayout_1.setHgap(20);
panel.setLayout(flowLayout_1);

panel.add(sendButton);
sendButton.setMargin(new Insets(0, 14, 0, 14));
sendButton.addActionListener(new sendActionListener());
sendButton.setText("发送");

panel.add(messageButton);
messageButton.setMargin(new Insets(0, 14, 0, 14));
messageButton.addActionListener(new MessageButtonActionListener());
messageButton.setText("信史");

panel_2.add(panel_5, BorderLayout.NORTH);
panel_5.setLayout(new BorderLayout());

toolbarActionListener toolListener = new toolbarActionListener();
panel_5.add(toolBar);
toolBar.setBorder(new BevelBorder(BevelBorder.RAISED));
toolBar.setFloatable(false);
toolBar.add(toolFontButton);
toolFontButton.addActionListener(toolListener);
toolFontButton.setFocusPainted(false);
toolFontButton.setMargin(new Insets(0, 0, 0, 0));
ImageIcon toolbarFontIcon = new ImageIcon(
MyQQ.class.getResource("/image/telFrameImage/toolbarImage/ToolbarFont.png"));
toolFontButton.setIcon(toolbarFontIcon);
toolFontButton.setToolTipText("设置字体颜色和格式");
toolBar.add(toolFaceButton);
toolFaceButton.addActionListener(toolListener);
toolFaceButton.setToolTipText("选择表情");
toolFaceButton.setFocusPainted(false);
toolFaceButton.setMargin(new Insets(0, 0, 0, 0));

ImageIcon toolbarFaceIcon = new ImageIcon(
MyQQ.class.getResource("/image/telFrameImage/toolbarImage/ToolbarFace.png"));
toolFaceButton.setIcon(toolbarFaceIcon);
toolBar.add(button);

button.addActionListener(toolListener);
button.setToolTipText("发送文件");
button.setFocusPainted(false);
button.setMargin(new Insets(0, 0, 0, 0));
ImageIcon toolbarPictureIcon = new ImageIcon(
MyQQ.class
.getResource("/image/telFrameImage/toolbarImage/ToolbarPicture.png"));
button.setIcon(toolbarPictureIcon);
toolBar.add(button_3);
button_3.addActionListener(toolListener);
button_3.setToolTipText("选择聊天场景");
button_3.setFocusPainted(false);
button_3.setMargin(new Insets(0, 0, 0, 0));
ImageIcon toolbarSceneIcon = new ImageIcon(
MyQQ.class.getResource("/image/telFrameImage/toolbarImage/ToolbarScene.png"));
button_3.setIcon(toolbarSceneIcon);
System.currentTimeMillis();
toolBar.add(messageMode);
messageMode.setText("消息模式");
panel_5.add(button_1, BorderLayout.EAST);
button_1.addActionListener(new Button_1ActionListener());
button_1.setMargin(new Insets(0, 0, 0, 0));
button_1.setText("<");
panel_2.add(panel_1);
panel_1.setLayout(new BorderLayout());
panel_1.add(scrollPane_1);
scrollPane_1
.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
sendText.setInheritsPopupMenu(true);
sendText.addKeyListener(new SendTextKeyListener());
sendText.setVerifyInputWhenFocusTarget(false);
sendText.setFont(new Font("宋体", Font.PLAIN, 12));
sendText.setMargin(new Insets(0, 0, 0, 0));
sendText.setDragEnabled(true);
sendText.requestFocus();
scrollPane_1.setViewportView(getSendText());

addWindowListener(new TelFrameClosing(tree));//添加窗体事件监听器
add(panel_3, BorderLayout.EAST);
panel_3.setLayout(new BorderLayout());
panel_3.add(scrollPane_2);
scrollPane_2
.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
scrollPane_2.setViewportView(label);
label.setIconTextGap(-1);
String imgPath = MyQQ.class
.getResource("/image/telFrameImage/telUserInfo.png")
+ "";
label.setText("<html><body background='" + imgPath
+ "'><table width='" + rightPanelWidth
+ "'><tr><td>用户名:<br>  " + user.getName()
+ "</td></tr><tr><td>主机名:<br>  " + user.getHost()
+ "</td></tr>" + "<tr><td>IP地址:<br>  " + user.getIp()
+ "</td></tr><tr><td colspan='2' height="
+ this.getHeight() * 2
+ "></td></tr></table></body></html>");//设置窗体右下的用户信息

panel_3.add(label_1, BorderLayout.NORTH);
label_1.setIcon(new ImageIcon(MyQQ.class
.getResource("/image/telFrameImage/telUserImage.png")));//设置窗体右边的用户图像
} catch (Exception e) {
e.printStackTrace();
}
setVisible(true); //显示窗体
setTitle("与好友" + user + "聊天交流中");
}

x8023x 2009-11-06
  • 打赏
  • 举报
回复
很简单啊 你都会公聊了 把服务器端存socket的map发给客户端,可以再客户端上添加个JList 让客户端自己选者和谁私聊 弄个私聊选者框 If选了 按发送的的时候就多发个socket给客户端 客户端就知道你和谁私聊了
iamrf 2009-11-06
  • 打赏
  • 举报
回复
以前学习的时候看过一个聊天系统的例子,是个教学用案例,效率上不敢说多么好,他的思路大概是这样的:
他是用线程来完成的,私聊时单独给这两个用户开一个线程。
当用户A想与用户B私聊时,用户A在页面上点击B选择私聊,服务器接收到A的请求信息,里面包含所需要的信息。
然后服务器向用户B发送一个信息,用户B接收到信息后反馈回服务器一个确认信息
如果同意私聊,则服务器为A和B单独建立一个线程,在其中完成私聊的工作。

不过我看的是J2EE版的,页面端貌似用的AJAX反转来接受服务器发给B用户的请求信息。但你要用swing写的话,可以写一个监听器来监听服务器的请求信息。
gao11811 2009-11-06
  • 打赏
  • 举报
回复
其实用qq嘛,多省力
苍蝇①号 2009-11-06
  • 打赏
  • 举报
回复
直接p2p多好啊
xuxinxin_happy 2009-11-06
  • 打赏
  • 举报
回复
公聊时 for 循环下0--254 ,私聊 ip
gao11811 2009-11-06
  • 打赏
  • 举报
回复
很简单。。
知道飞鸽传书吗?既然你能在服务器得到所有建立连接的hasMap,那这个map发送并显示在客户端不就好了,客户端通过选择相应的用户,将信息和对话用户的特征发送到服务器,然后由服务器转发,结束。

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧