一个有关QQ信息的问题

huang6326246 2010-03-25 10:23:43
前段时间看完了一本网络编程的书——《TCP/IP》,是用java来讲解的,有个问题一直很困惑不解。就是书里有个例子是讲解聊天室程序的,程序是这样的:服务器端程序收到客户端程序发送过来的信息后,检测所有连接,然后向所有连接发送从客户端收到的信息。在聊天室程序中,客户端发送信息是根据服务器的IP地址来发送的,而服务器是根据已建立的连接来发送信息的。
那么我想问的是:两个QQ客户端的通信具体是怎么样实现的?两个QQ客户端根据服务器IP地址和服务器建立连接后,第一个QQ客户端将信息发送到服务器后,服务器是怎么样将信息发送到第二个指定的QQ客户端的?根据QQ号码?那又是怎么样实现的?各位高手能不能解释一下,小弟实在想不明白。
...全文
221 19 打赏 收藏 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
huang6326246 2010-03-29
  • 打赏
  • 举报
回复
慢慢学习代码了。
huang6326246 2010-03-27
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 ivorytower 的回复:]
底层都是使用的Java Socket。对于QQ,你可以理解了有一个list,存储了一些QQ号,当一个QQ要与另外的qq聊天的时候,信息发过来,服务器那边就会去查找对应的qq,然后把信息转发出去。我给你看看两边的通讯代码吧:

Java code

/** *多线程socket服务端 * @author 49 */
package socketThread;
import java……
[/Quote]有代码非常好,谢谢,这个很有用,但是我还希望能用文字解释一下。
amdgaming 2010-03-26
  • 打赏
  • 举报
回复
学习。。。。up
ChDw 2010-03-26
  • 打赏
  • 举报
回复
一开始做聊天的话,应该尝试做最简单的。就是所有客户端直接连接到服务器的特定端口上,并保持长连接。

这样服务器就会维持有整个系统中已登录用户与Socket连接的映射。

当A向B用户发消息时,A向服务器发送数据包,指定目标为B,消息内容等。
服务器查找用户B的IP,如果找到就相应的Socket,就可以实现转发了。



在自己不熟悉的情况下不要一开始就试图做太复杂的,必须逐步增加功能和改进才是正确的方法
jimyx123 2010-03-25
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 huang6326246 的回复:]
引用 4 楼 huang6326246 的回复:
引用 2 楼 jimyx123 的回复:
外网TCP直连,内网UDP打洞
什么叫UDP打洞?你的回答让我更困惑了
噢,能不能具体解释一下我发的问题?你就说个TCP,当没说!
[/Quote]
粗略地说
外网的话就直接用TCP建立连接,连接一旦建立想发就发
内网的话不能直接建立连接,可以用UDP打洞
因为内网要访问外网就得跟网关申请端口号
端口号会有存活时间,中间服务器负责维护这临时端口
当机子想和另一个内网机子通信 就先跟服务器要端口再建立连接
justchenjie 2010-03-25
  • 打赏
  • 举报
回复
我也不明白楼上讲的什么打洞...在服务器端用一个对象保存已与服务建立链接的客户端,为这个客户端分配一个独立的socket。它客户端发来个信息时,首先这个信息里有这个客户端的QQ号码以及要联系的QQ号码,到服务器时就能找到自己独有的socket。当然另一个客户端也在服务器上有自己独有的socket的,他们通过各自服务器端的socket进行通信(在服务器端进行消息转发)。
  • 打赏
  • 举报
回复
底层都是使用的Java Socket。对于QQ,你可以理解了有一个list,存储了一些QQ号,当一个QQ要与另外的qq聊天的时候,信息发过来,服务器那边就会去查找对应的qq,然后把信息转发出去。我给你看看两边的通讯代码吧:

/** *多线程socket服务端 * @author 49 */
package socketThread;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
//import java.io.PrintWriter;
import java.net.*;
import java.util.concurrent.*;
import wcdjsrc.dbSocket;
import javax.swing.*;

public class serverSocket {
private int port=10000;
private ServerSocket serverSocket;
private ExecutorService executorService;//线程池
private final int POOL_SIZE=10;//单个CPU线程池大小
public serverSocket() throws IOException{
serverSocket=new ServerSocket(port);
//Runtime的availableProcessor()方法返回当前系统的CPU数目. executorService=Executors.newFixedThreadPool(
Runtime.getRuntime().availableProcessors()*POOL_SIZE);
System.out.println("服务器启动");
}
public void service(){
while(true){
Socket socket=null;
try {
//接收客户连接,只要客户进行了连接,就会触发accept();从而建立连接 socket=serverSocket.accept();
executorService.execute(
new Handler(socket));
}
catch (Exception e) {
e.printStackTrace();
}
}
}
// public static void main(String[] args) throws IOException {
// new serverSocket().service();
// }
}

class Handler implements Runnable{
private Socket socket;
private dbSocket ds=null;
public Handler(Socket socket){
this.socket=socket;
}
private PrintStream getWriter(Socket socket) throws IOException{
OutputStream socketOut=socket.getOutputStream();
return new PrintStream(socketOut,true,"UTF-8");
}

private BufferedReader getReader(Socket socket) throws IOException{
InputStream socketIn=socket.getInputStream();
return new BufferedReader(new InputStreamReader(socketIn,"UTF-8"));
}

public String echo(String msg){
return "echo:"+msg;
}

public void run(){
try {
System.out.println(
"New connection accepted "+socket.getInetAddress()+":"+socket.getPort()); BufferedReader br=getReader(socket);
PrintStream pw=getWriter(socket);
String msg=null; String pwwords="";
while((msg=br.readLine())!=null){
System.out.println(msg);
//接收到的数据
pwwords = "leaderusertrue";
pw.print(pwwords);
//返回给手机端的数据
// br.close();
// socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(socket!=null)
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
bbb332 2010-03-25
  • 打赏
  • 举报
回复
没有学过,帮顶。。。。。
ladybirds2008 2010-03-25
  • 打赏
  • 举报
回复
这个 用到的技术好像挺多的啊,跟电子技术,协议有很大关系啊。。。技术很复杂感觉。。。。
huang6326246 2010-03-25
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 chdw 的回复:]
第一个QQ客户端将信息发送到服务器后,服务器是怎么样将信息发送到第二个指定的QQ客户端的、
----

服务器会维持有所有已登录QQ用户的IP与端口的,所以在这种情况下服务器只要找到第二个指定QQ的IP与端口然后发送数据就可以了。

不过QQ实际上会使用直接连接或UDP穿透,可以避免服务器压力太大的。
[/Quote]噢,有点头绪了,还能解释细一点就好了,谢谢哈
huang6326246 2010-03-25
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 huang6326246 的回复:]
引用 2 楼 jimyx123 的回复:
外网TCP直连,内网UDP打洞
什么叫UDP打洞?你的回答让我更困惑了
[/Quote]噢,能不能具体解释一下我发的问题?你就说个TCP,当没说!
ChDw 2010-03-25
  • 打赏
  • 举报
回复
第一个QQ客户端将信息发送到服务器后,服务器是怎么样将信息发送到第二个指定的QQ客户端的、
----

服务器会维持有所有已登录QQ用户的IP与端口的,所以在这种情况下服务器只要找到第二个指定QQ的IP与端口然后发送数据就可以了。

不过QQ实际上会使用直接连接或UDP穿透,可以避免服务器压力太大的。
ChDw 2010-03-25
  • 打赏
  • 举报
回复
UDP打洞的意思是两台在不同局域网内的机器通过一些特定的方法建立起UDP连接。

这个解释有点复杂,如果你刚刚开始做可以暂时不要考虑。
huang6326246 2010-03-25
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 jimyx123 的回复:]
外网TCP直连,内网UDP打洞
[/Quote]什么叫UDP打洞?你的回答让我更困惑了
huang6326246 2010-03-25
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 xiesisi3 的回复:]
P2P
[/Quote]能不能讲具体一点?小弟新手,谢谢
jimyx123 2010-03-25
  • 打赏
  • 举报
回复
外网TCP直连,内网UDP打洞
xiesisi3 2010-03-25
  • 打赏
  • 举报
回复
P2P
huang6326246 2010-03-25
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 tagalin 的回复:]
我也做过聊天室程序,不过只是作为j2se练手的
实际应用中不要研究那么深的,只要知道socket的原来就行了,除非你就想向b/s发展
ps:我也是菜鸟一个,如果说的不对还请见谅
[/Quote]不想当将军的兵不是好兵啊!唉......
tagalin 2010-03-25
  • 打赏
  • 举报
回复
我也做过聊天室程序,不过只是作为j2se练手的
实际应用中不要研究那么深的,只要知道socket的原来就行了,除非你就想向b/s发展
ps:我也是菜鸟一个,如果说的不对还请见谅

62,620

社区成员

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

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