前两天发了个帖子经过各位指点目前已经把java的socket编程的多线程已经弄出来大家群聊没有问题但是我现在发现如果要实现单对单的私聊就不知道怎么弄了以前的思路是在主进程中定义一个结构体,来保存每个客户端连接的socket句柄当A向B私聊的时候服务器看到了私聊指令就从结构体当中找到B的socket句柄来向B发送数据这是最基本的思路了但是我在java里面该如何实现呢?比如我要把用户ID,用户名,帮会ID这些存放在一个结构体当中怎么存呢另外我看到java里面有arraylist我觉得比较象结构体但在serversocket的accept之后我打印了一下数据他只有远程ip本地端口和一个端口的内容
我不知道这个端口内容为什么不对,比如我设定的端口为5000每次他会打印出来的值不一样,连接一个就不一样,而本地端口一直都是5000,因为我调试是在本机,客户端和服务端都在一起,所以不知道是不是这个原因造成的,如果不是的话我想这个端口是不是就是我要的句柄
请各位老大指点

解决方案 »

  1.   

    - -!又看到你了  既然你已经掌握了群聊,而对一对一的聊困惑,我觉得这个不应该。  至于怎么存我觉得都可以,比如用个map,key来规定固定的用户信息,而value存放的是客户的socket。
      
      这样你就可以和任何人通信了。
     
      
      

  2.   

    Map<用户唯一标示,用户socket>或者干脆记录用户ip,让他们俩udp会话得了。
      

  3.   

    楼上的朋友其实思路我倒是蛮清楚的就是不知道怎么样的代码在java里面比较合适java真的挺简单的,只是目前我不了解其特性如果可以的话能否把你上次给我的博客里面的代码完善成一个可以私聊的版本我看看另外如果方便的话告诉我一下你的qq我有点问题想请教你呢
      

  4.   

    另外3楼的朋友我目前用的客户端是flash的,它不支持udp,只能tcp呵呵如果可以的话给点代码学习一下
      

  5.   

    楼上的所有朋友首先感谢你们的回答不过请大家理解一下我的意思我不是不了解socket编程的思路我只是想具体看在java里面如何实现而不是大家给我点编程的思路,能帮忙的就贴点代码给看看,感谢了
      

  6.   

    点对点的话,照你现在看来只能通过服务端中转。也就是 A 要与 B 通话,应该是这样的流程:A ---发送消息a---> 服务端 ---转发消息a---> B
      

  7.   

    我也是新手,我猜猜用map是可以解决的,一个socket作为key,另一个如果要建立私聊的话,就紧跟着那些代码写上map的初始化语句,将另外一个socket作为value写进来
      

  8.   

    火龙果
    你说的很对啊
    有代码吗?
    14楼的朋友
    我做了一个hashmap,里面保存了用户id和用户的socket
    服务器如果发现是需要私聊则,在hashmap里面去检索需要接受的用户id,如果找到了则给这个socket发信息我现在的问题在找到这个socket后不知道怎么用这个socket发出去
      

  9.   

    我的代码如下String uid=userinfo[2];
    Set<Map.Entry<String, Socket>> mySet = new NewChatServer().container.entrySet();
    Iterator<Map.Entry<String, Socket>>it = mySet.iterator();
    String message = userinfo[1];
    while (it.hasNext()) {//如果列表中还有客户
    Map.Entry<String, Socket> me = it.next();
    Socket tempClient = me.getValue();
        String key = me.getKey();
        if(key.equals(uid)){
         //问题就在这里了,找到了对方后我的temclient该怎么写能把信息发出去
        }
    }
    java版的朋友思路都很多没有人愿意给代码啊
      

  10.   

    我现在的问题在找到这个socket后不知道怎么用这个socket发出去
    Socket 可以获得 OutputStream,把数据 write 进去就可以了。
      

  11.   


    你的思路不是很对吗?
    发送数据首先找到接收方ID,根据ID找到Socket。
    利用发送方Socket.getInputStream,保存到byte[],然后利用接收方Socket.getOutputStream().write();写入,最后Socket.getOutputStream().frush()就发送了感觉长连接,短连接都可以。
      

  12.   

    私聊还不简单啊,用UDP来做超级简单
      

  13.   

    我滴神啊我说了一万遍了我要的不是思路,思路我几年前就有了,delphi、c++都实现过还有我不能做udp通信,我这里客户端只能用tcp大家也太敷衍我了嘛唉,实在没人帮手我再想想办法
      

  14.   


    你要代码?难道就为了这代码,让别人从头写个聊天程序,来测试这段代码?你要是问算法,或者某些能直接使用 main 方法得出结果的东西,那贴代码倒无所谓,像这样的网络应用程序,除非别人正好有个跟你一模一样的东西,否则你随便到哪里去问都是不可能的,没人会贴代码!
      

  15.   

    你用 TCP 也是一样的,也可以通过前面所说的 Map 找到 Socket 对象,写数据进去就可以了。
      

  16.   

    我滴神就是一个服务端发送数据两行代码啊况且我上面已经把代码都贴出来了只是在判断符合条件后我那个地方如何发,告诉我一下就是了火龙果,你看起来回答的那么严肃认真的麻烦你能不能理解一下我的意思哦,你要不愿意帮我写就算了,不过我真的知道我的思路是没错的其实我已经发出去了,只是在发送成功后socket的send和recv在java里面的对应关系我看起来觉得有点混乱,想看看你们怎么写的,我看有没有助于对这个java的socket的深入理解结果4颗红星就很严肃的纸上谈兵
      

  17.   

    我是一直想搞清楚在java里面的serversocket这个对象里面为什么没有找到对特定客户端发送数据的东西还有就是socket对象我一直想搞清楚哪个是对应socket的send方法和recv方法只要能把这两点搞清楚基本的多线程服务端程序会既简单又稳定的单就这么简简单单的两点红星大哥都不愿意给几行简短的代码给看看我遁了,我在研究2天开搞线程池和内存池其实java是很有亲和力的,就是sun把api的名字弄得怪里怪气的,容易把人弄迷糊
      

  18.   

    每个用户都应该有个id
    每条消息都应该有发送者id和接收者id
    服务器在处理消息的时候,通过id找到具体的socket来发送就可以了
    在服务端可以把每个socket当作session来看待吧建议用Apache MINA框架
    百度一下资料很多的
    NIO比多线程socket好很多
    MINA框架也让你摆脱网络细节,只用做好业务逻辑就ok了
      

  19.   


    就是实现基于java服务端的tcp连接的私聊
      

  20.   

    3个类
    //User
    import java.io.Serializable;public class User implements Serializable { private static final long serialVersionUID = 520335207752011L;
    private String id;
    private String name;
    private int age;
    public User(String id, String name, int age) {
    this.id = id;
    this.name = name;
    this.age = age;
    }
    public String getId() {
    return id;
    }
    public void setId(String id) {
    this.id = id;
    }
    public String getName() {
    return name;
    }
    public void setName(String name) {
    this.name = name;
    }
    public int getAge() {
    return age;
    }
    public void setAge(int age) {
    this.age = age;
    }

    public String toString() {
    return id + ":" + name + ":" + age;
       }
    }
    //Server
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;public class SServer { private ServerSocket server;
    private Socket socket;
    public SServer() {
    try {
    server = new ServerSocket(54321);
    socket = server.accept();
    SendThread st = new SendThread();
    RecviceThread rt = new RecviceThread();
    new Thread(st).start();
    new Thread(rt).start();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }

    private class SendThread implements Runnable {
    private ObjectOutputStream output;
    private boolean isSend = true;
    public SendThread() {
    try {
    output = new ObjectOutputStream(socket.getOutputStream());
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    public void run() {
    int t = 0;
    try {
    while(isSend) {
    User user = new User("1000" + t, "serverUser" + t, 20 + t);
    output.writeObject(user);
    output.flush();
    t ++;
    Thread.sleep((long) (Math.random()*2000));
    }
    }catch(Exception e) {

    }finally {
    try {
    socket.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }
    }

    private class RecviceThread implements Runnable {
    private ObjectInputStream input;
    private boolean isRecvice = true;
    public RecviceThread() {
    try {
    input = new ObjectInputStream(socket.getInputStream());
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    public void run() {
    try {
    while(isRecvice) {
    User user = (User)input.readObject();
    System.out.println(user);
    Thread.sleep((long) (Math.random()*2000));
    }
    }catch(Exception e) {

    }finally {
    try {
    socket.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }
    }

    public static void main(String args[]) {
    new SServer();
    }
    }
    //Client
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.net.Socket;
    import java.net.UnknownHostException;public class CClient { private Socket socket;
    public CClient() {
    try {
    socket = new Socket("127.0.0.1", 54321);
    SendThread st = new SendThread();
    RecviceThread rt = new RecviceThread();
    new Thread(st).start();
    new Thread(rt).start();
    } catch (UnknownHostException e) {
    e.printStackTrace();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    private class SendThread implements Runnable {
    private ObjectOutputStream output;
    private boolean isSend = true;
    public SendThread() {
    try {
    output = new ObjectOutputStream(socket.getOutputStream());
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    public void run() {
    int t = 0;
    try {
    while(isSend) {
    User user = new User("1000" + t, "clientUser" + t, 20 + t);
    output.writeObject(user);
    output.flush();
    t ++;
    Thread.sleep((long) (Math.random()*2000));
    }
    }catch(Exception e) {

    }finally {
    try {
    socket.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }
    }

    private class RecviceThread implements Runnable {
    private ObjectInputStream input;
    private boolean isRecvice = true;
    public RecviceThread() {
    try {
    input = new ObjectInputStream(socket.getInputStream());
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    public void run() {
    try {
    while(isRecvice) {
    User user = (User)input.readObject();
    System.out.println(user);
    Thread.sleep((long) (Math.random()*2000));
    }
    }catch(Exception e) {

    }finally {
    try {
    socket.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }
    }
    public static void main(String args[]) {
    new CClient();
    }
    }
    这个我已经测试没问题,你自己看看研究下。
      

  21.   

    说明Server与Client两个都是采用两个线程
    一个线程发一个收
    就可以你想发什么,都可以,连续发,连续接。我们这边就是采用简单的连续发,版主自己看看。
      

  22.   

    楼上的估计你是没有仔细看我的需求了呵呵你这种连续发连续接的,我接触java5个小时候就搞定了我是想看你们做的私聊的而不是这种逻辑的不过我看java版也没指望了我结贴