前段时间看完了一本网络编程的书——《TCP/IP》,是用java来讲解的,有个问题一直很困惑不解。就是书里有个例子是讲解聊天室程序的,程序是这样的:服务器端程序收到客户端程序发送过来的信息后,检测所有连接,然后向所有连接发送从客户端收到的信息。在聊天室程序中,客户端发送信息是根据服务器的IP地址来发送的,而服务器是根据已建立的连接来发送信息的。
那么我想问的是:两个QQ客户端的通信具体是怎么样实现的?两个QQ客户端根据服务器IP地址和服务器建立连接后,第一个QQ客户端将信息发送到服务器后,服务器是怎么样将信息发送到第二个指定的QQ客户端的?根据QQ号码?那又是怎么样实现的?各位高手能不能解释一下,小弟实在想不明白。
那么我想问的是:两个QQ客户端的通信具体是怎么样实现的?两个QQ客户端根据服务器IP地址和服务器建立连接后,第一个QQ客户端将信息发送到服务器后,服务器是怎么样将信息发送到第二个指定的QQ客户端的?根据QQ号码?那又是怎么样实现的?各位高手能不能解释一下,小弟实在想不明白。
----服务器会维持有所有已登录QQ用户的IP与端口的,所以在这种情况下服务器只要找到第二个指定QQ的IP与端口然后发送数据就可以了。不过QQ实际上会使用直接连接或UDP穿透,可以避免服务器压力太大的。
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();
}
}
}
}
外网的话就直接用TCP建立连接,连接一旦建立想发就发
内网的话不能直接建立连接,可以用UDP打洞
因为内网要访问外网就得跟网关申请端口号
端口号会有存活时间,中间服务器负责维护这临时端口
当机子想和另一个内网机子通信 就先跟服务器要端口再建立连接
实际应用中不要研究那么深的,只要知道socket的原来就行了,除非你就想向b/s发展
ps:我也是菜鸟一个,如果说的不对还请见谅
服务器查找用户B的IP,如果找到就相应的Socket,就可以实现转发了。在自己不熟悉的情况下不要一开始就试图做太复杂的,必须逐步增加功能和改进才是正确的方法