社区
Java SE
帖子详情
socket通信中如何标识当前用户?
whatisma
2010-08-18 10:19:57
多线程的 服务端-多客户端 模式的socket通信客户端退出时怎么知道是哪个用户退出了?
也就是说服务端怎么保存各个线程中的用户信息。
...全文
695
24
打赏
收藏
socket通信中如何标识当前用户?
多线程的 服务端-多客户端 模式的socket通信客户端退出时怎么知道是哪个用户退出了? 也就是说服务端怎么保存各个线程中的用户信息。
复制链接
扫一扫
分享
转发到动态
举报
AI
作业
写回复
配置赞助广告
用AI写文章
24 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
pywepe
2010-08-25
打赏
举报
回复
[Quote=引用楼主 whatisma 的回复:]
多线程的 服务端-多客户端 模式的socket通信客户端退出时怎么知道是哪个用户退出了?
也就是说服务端怎么保存各个线程中的用户信息。
[/Quote]
协议
h47966392
2010-08-25
打赏
举报
回复
监听事件 具体做法 参考mina里面的源码 了解下思想就OK了
jywbd
2010-08-25
打赏
举报
回复
你客户端登陆的时候,首先告诉服务器我登陆了,在服务端记录下来,当你退出的时候,也向服务器说下,我退出了,服务器然后找到你先前登陆进来的记录,进行必要的修改,比方说,删除,这样就可以了
dongge0701
2010-08-25
打赏
举报
回复
在服务器的class里建立一个List<socket> sl链,每当有一个socket线程加入时就 sl.add()添加到sl里;当某个线程结束条件出现时,用一个变量标记该线程,然后sl.remove();被标记的就是关闭的线程
fenseyouyu
2010-08-25
打赏
举报
回复
直接将用户套接字存放List或Map中,是会报错的,如要保存需将 管理各个用户的线程保存在List或Map中。
需要停止 则调用用户线程中的停止方法,(自己写的停止方法)
http://download.csdn.net/source/536582
这个项目是我写的c/s模式的建议聊天室,其中用到套接字与对象流,有个在线列表就用到了获得所有用户信息,我采用的就是将分配给用户的线程 保存至Map中。
如果一个用户退出就服务端就根据发出退出请求的用户名,找到用户的线程并且kill掉。
humanity
2010-08-25
打赏
举报
回复
既然要有用户信息,那就表明客户端建立 TCP 连接之后,马上去发出登录信息给服务器,服务器应该将这个用户信息与这个连接对应的Socket(或这个 Socket 对应的线程绑定(比如有一个 map 表))。
private Map users = new HashMap();
while(running){
Socket client = serverSocket.accept();
new WorkerThread(client).start();
)
...
class WorkerThread extends Thread{
private String userId;
private ChannelThread reader;
private ChannelThread writer;
...
public void run() {
...
try {
// 这个客户端线程如果输入了登录信息,我们就把这个 userId 保存下来。
// 处理 Socket I/O 交互.
InputStream input = socket.getInputStream();
OutputStream output = socket.getOutputStream();
...
// 如果是全双工,Input 和 Output 用单独的线程处理 I/O 操作。
// 这里,我们的 writer 和 reader 的任何一个线程在检测到异常时或者
// 收到客户端发送的 Logout 消息都应该报告给(比如,通过 notifyAllActiveChanneslQuit())
// WorkerThread,想办法通知另一个 reader/writer 线程退出。Reader/Writer 都
// 退出之后我们就可以关闭 Socket 了,并告诉服务器,这个 socket 对应的用户已经
// 注销了,不管是 SocketException/IOException 导致的还是用户主动发出
// Logout 消息。这里构造方法只有一个参数,可以考虑成内部类实现。
// 这里要注意线程同步,不小心的话可能有死锁。不用同步的话,
// 可能会丢失状态,导致没接收到退出通知让WorkerThread 一直在等。
// 当然直接 socket.close() 让其它线程出异常而退出也行,
// 但不优雅的方式导致 CLOSE_WAIT 太多。
this.writer = new WriterChannelThread(output);
this.reader = new ReaderChannelThread(input);
reader.start();
writer.start();
// 等等 reader 和 writer 两个线程都退出。
reader.join();
writer.join();
// 在迫不捕获到异常之后通知这个 WorkerThread 或 主线程这个线程已经退出了。
} finally {
最后把这个注销,不管是他主动注销还是 Socket 断线了。
users.remove(this.userId);
}
}
private void notifyAllActiveChannelsQuit() {
this.writer.quit();
this.reader.quit();
}
}
huadis
2010-08-25
打赏
举报
回复
传个标识
sunhui5415
2010-08-20
打赏
举报
回复
访问一下服务器
whatisma
2010-08-20
打赏
举报
回复
[Quote=引用 10 楼 yaoweijq 的回复:]
socket客户端连服务端总得有IP 端口号吧
用这两个来标识一个socket就可以了
正常退出,异常退出只要有相应的监听机制就完全可以保证服务器端捕获退出事件
[/Quote]
客户端的IP肯定是变化的,如果退出时通过IP再查询保存的用户名和当前IP关系这样倒也可以。但是如果是客户端双开或多开呢?再或者是一个局域网内的多个用户呢,这时的出口IP肯定是一样的,这方法就没用了吧。
[Quote=引用 12 楼 maquan 的回复:]
当客户端停掉时(无论主动退出还是网络掉线),也应该是这个服务线程首先获知了“该客户端停掉”这个事件的,那它当然应该知道现在停掉的是哪个客户端啰,因为Hashtable中保存的东西就是它写进去的嘛。
[/Quote]
这个不是很明白,服务线程怎么获知“该客户端停掉”?也是用10楼说的监听方法吗,能否说的详细点?Hashtable里保存的是所有登录的用户信息。
刚接触这些,可能问题比较多,问题描述也不是很清楚,非常谢谢大家的回答。也看过网上的比较多的例子,都感觉是比较简单的通信,没有考虑复杂情况。
whatisma
2010-08-20
打赏
举报
回复
[Quote=引用 15 楼 maquan 的回复:]
这个应该是 socket 通信的问题呀。那个服务线程应该是跟对应的客户端保持 TCP 连接的,如果断掉了,那就可以认为“该客户端停掉”嘛。
[/Quote]
能否给个代码片段?
maquan
2010-08-20
打赏
举报
回复
[Quote=引用 14 楼 whatisma 的回复:]
这个不是很明白,服务线程怎么获知“该客户端停掉”?也是用10楼说的监听方法吗,能否说的详细点?[/Quote]
这个应该是 socket 通信的问题呀。那个服务线程应该是跟对应的客户端保持 TCP 连接的,如果断掉了,那就可以认为“该客户端停掉”嘛。
[Quote=引用 14 楼 whatisma 的回复:]
Hashtable里保存的是所有登录的用户信息。[/Quote]
这个当然是的,那么,是谁保存进去的呢?应该是“服务线程”吧?
————————
基于CSDN论坛提供的插件扩展功能,自己做了个签名档工具,
分享给大家
,欢迎技术交流 :)
whatisma
2010-08-19
打赏
举报
回复
用户的用户名和密码已经用的Hashtable保存了的。
3、4楼感觉没理解我的问题,我要的是用户退出时获得用户信息,也可以理解为用户退出时怎么从保存的Hashtable里面取数据,总要有个where条件才能取吧。
另外个2楼的方法让客户端来主动发送信息,那如果客户端是意外退出的呢,根本没向服务端发送命令就退了。
closewbq
2010-08-19
打赏
举报
回复
这是我博客中简单写的一个聊天的小程序
当每个socket连接的时候,给socket分配一个ID。
maquan
2010-08-19
打赏
举报
回复
[Quote=引用 5 楼 whatisma 的回复:]
用户的用户名和密码已经用的Hashtable保存了的。
3、4楼感觉没理解我的问题,我要的是用户退出时获得用户信息,也可以理解为用户退出时怎么从保存的Hashtable里面取数据,总要有个where条件才能取吧。
另外个2楼的方法让客户端来主动发送信息,那如果客户端是意外退出的呢,根本没向服务端发送命令就退了。
[/Quote]
既然“已经用Hashtable保存了”,那按说应该是负责为特定客户端服务的那个服务线程做的保存吧?
当客户端停掉时(无论主动退出还是网络掉线),也应该是这个服务线程首先获知了“该客户端停掉”这个事件的,那它当然应该知道现在停掉的是哪个客户端啰,因为Hashtable中保存的东西就是它写进去的嘛。
————————
基于CSDN论坛提供的插件扩展功能,自己做了个签名档工具,
分享给大家
,欢迎技术交流 :)
evangelionxb
2010-08-19
打赏
举报
回复
当客户端启动时。
客户端发送InetAddress类的getHostName(),和getHostAddress属性给服务端。
保存的话用数组,list。
read_act
2010-08-19
打赏
举报
回复
多线程的 服务端-多客户端 模式的socket通信客户端退出时怎么知道是哪个用户退出了?
其实是两问题:1。服务器怎么分辨客户端,2,退出如何通知服务器
解决 : 1.建个属性类里面包装所有客户端信息,包括socket和流
2。用户点了角上的叉才退出嘛, 监听那个扭。
yaoweijq
2010-08-19
打赏
举报
回复
socket客户端连服务端总得有IP 端口号吧
用这两个来标识一个socket就可以了
正常退出,异常退出只要有相应的监听机制就完全可以保证服务器端捕获退出事件
peiqu123
2010-08-19
打赏
举报
回复
每个客户相当一个进程,该进程ID唯一标识应该是主机+端口号,不知道楼主想问的是不是这个?
whatisma
2010-08-19
打赏
举报
回复
[Quote=引用 7 楼 evangelionxb 的回复:]
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
public class ChatClient extends Frame {
Socket s = null;
DataOutputStream dos = null;
DataInputStream dis = nu……
[/Quote]
这个虽然没有解决我的问题,还是先谢过了。
继续等待...
evangelionxb
2010-08-19
打赏
举报
回复
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
public class ChatClient extends Frame {
Socket s = null;
DataOutputStream dos = null;
DataInputStream dis = null;
private boolean bConnected = false;
TextField tfTxt = new TextField();
TextArea taContent = new TextArea();
Thread tRecv = new Thread(new RecvThread());
public static void main(String[] args) {
new ChatClient().launchFrame();
}
public void launchFrame() {
setLocation(400, 300);
this.setSize(300, 300);
add(tfTxt, BorderLayout.SOUTH);
add(taContent, BorderLayout.NORTH);
pack();
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent arg0) {
disconnect();
System.exit(0);
}
});
tfTxt.addActionListener(new TFListener());
setVisible(true);
connect();
tRecv.start();
}
public void connect() {
try {
s = new Socket("127.0.0.1", 8888);
dos = new DataOutputStream(s.getOutputStream());
dis = new DataInputStream(s.getInputStream());
System.out.println("connected!");
bConnected = true;
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void disconnect() {
try {
dos.close();
dis.close();
s.close();
} catch (IOException e) {
e.printStackTrace();
}
/*
try {
bConnected = false;
tRecv.join();
} catch(InterruptedException e) {
e.printStackTrace();
} finally {
try {
dos.close();
dis.close();
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
*/
}
private class TFListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
String str = tfTxt.getText().trim();
//taContent.setText(str);
tfTxt.setText("");
try {
//System.out.println(s);
dos.writeUTF(str);
dos.flush();
//dos.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
private class RecvThread implements Runnable {
public void run() {
try {
while(bConnected) {
String str = dis.readUTF();
//System.out.println(str);
taContent.setText(taContent.getText() + str + '\n');
}
} catch (SocketException e) {
System.out.println("退出了,bye!");
} catch (EOFException e) {
System.out.println("推出了,bye - bye!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
加载更多回复(4)
C++
socket
通信
详解
Socket
是什么
Socket
是应用层与TCP/IP协议族
通信
的
中
间软件抽象层,它是一组接口。在设计模式
中
,
Socket
其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在
Socket
接口后面,对
用户
来说,一组简单的接口就是全部,让
Socket
去组织数据,以符合指定的协议。 原作者将
socket
通信
类比为打电话这一生活场景。这里我把TCP服务器比作政府某一服务部门能,TCP客户端比作企业
中
某一部门电话,描述这一过程,恰好就像是
socket
通信
,服务部门提供服务,企业部门申请服务。 要实现
通信
,首先政府
Socket
的
通信
原理和使用
目录 一、什么是
Socket
? 二、
Socket
通信
过程 2.1
通信
过程介绍 2.2 实现TCP建立连接的三次握手过程 三、 使用
Socket
进行
通信
【php】 3.1 PHP
中
Socket
常量和函数介绍 3.2 php实现
Socket
通信
过程 一、什么是
Socket
?
Socket
的
中
文翻译过来就是“套接字”。套接字是什么,我们先来看看它的英文含义:插座。
socket
起源于Unix,而Unix/Li........................
Socket
通信
原理
整理和总结了一下大家常遇到的问题: 1. 客户端
socket
发送消息后,为什么服务端
socket
没有收到? 2. 使用while 循环实现连续输入,是不是就是多线程模式? 3. 对多线程处理机制不是很明白,希望详细讲解? 4. 希望详细讲解Server
Socket
Channel和
Socket
Channel与ServerSoket和
Socket
的区别? 5. 希望有详细的例子,可以...
计算机网络
socket
通信
底层原理
Socket
是网络
通信
的端点,通常用于在客户端和服务器之间建立连接并交换数据。
Socket
通信
可以基于不同的传输协议,如TCP(传输控制协议)和UDP(
用户
数据报协议)。
Socket
通信
是计算机网络
中
一种重要的
通信
方式,涉及多个层次的协议和机制。通过理解
Socket
通信
的底层原理,可以更好地设计和实现网络应用程序。希望这些信息对你有所帮助!如果有更多问题或需要进一步的帮助,请随时提问。好的,让我们继续深入探讨
Socket
通信
的底层原理和相关技术细节。
Socket
通信
机制(学习总结)
一、什么是
Socket
: 1、
Socket
是两个程序进行双向数据传输的网络
通信
的端点,由一个地址和一个端口来
标识
。 2、两种
通信
方式:有连接方式TCP、无连接方式UDP(
用户
数据报协议)。二、有连接方式TCP 1、
通信
双方在开始时必须进行一次连接过程(三次握手),建立一条
通信
链路。
通信
链路提供了可靠的,全双工的字节流服务。
Socket
是两个进程间
通信
链的端点,每个
socket
有两个流:一个
Java SE
62,634
社区成员
307,269
社区内容
发帖
与我相关
我的任务
Java SE
Java 2 Standard Edition
复制链接
扫一扫
分享
社区描述
Java 2 Standard Edition
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章