【问题标题】:Port issue with Java socketJava套接字的端口问题
【发布时间】:2013-05-29 13:50:53
【问题描述】:

我首先使用线程和套接字,所以我正在尝试进行聊天(本地)

ClientA(实际上是服务器):

public class ClientA {

    public static void main(String[] args) {

        ServerSocket servsock = null;
        try {
            servsock = new ServerSocket(9998);
            Socket conn = servsock.accept();
            System.out.println("server socket listening on local port : " + servsock.getLocalPort());
            System.out.println("socket listening on local port : " + conn.getLocalPort());
            System.out.println("socket listening on port : " + conn.getPort());
            servsock.close();

            TReadingSock tls = new TReadingSock(conn);
            tls.start();
            TWritingSock tes = new TWritingSock(conn);
            tes.start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

客户B,实际客户:

public class ClientB {

    public static void main(String[] args) {

        Socket sock = null;
        try {
            sock = new Socket("localhost", 9998);
            System.out.println("socket listening on local port : " + sock.getLocalPort());
            System.out.println("socket listening on port : " + sock.getPort());
        } catch (IOException e) {
            e.printStackTrace();
        }

        TReadingSock tls = new TReadingSock(sock);
        tls.start();
        TWritingSock tes = new TWritingSock(sock);
        tes.start();
    }
}

打印显示:

客户 A:

server socket listening on local port : 9998
socket listening on local port : 9998 
socket listening on port : 50875

客户 B:

socket listening on local port : 50875  
socket listening on port : 9998

因此,尽管看起来很愚蠢,但我在理解整个套接字方面存在严重问题,我唯一得到的就是我的程序正在侦听不同的端口,我不明白为什么。我想这对某些人来说一定很明显,所以我请求你的帮助来启发我!

提前致谢。

编辑:感谢您的所有回答。问题是,对我来说,您需要一个 ServerSocket 来侦听端口并接受任何尝试连接的客户端。完成后,它返回一个 Socket 对象,我将其传递给我的线程,以便它们可以完成工作。那是给客户A的。客户端 B 只是创建一个 Socket,它将尝试连接到 9998 端口,这是我用我的 ServerSocket 监听的端口。然后它将它传递给它的线程。问题是,当我启动客户端(A 然后 B)并在控制台 A 中写入时,控制台 B 上没有任何反应(也许我应该早点指定,抱歉)。

我猜这是由于我的套接字正在使用的端口。我检查了一些教程,即使在阅读了您的回复之后,我也看不出有什么问题,所以要么我遗漏了一些非常明显的概念,要么它不是连接本身,而是我处理连接的方式。以防万一,我会发布线程的内容:

public class TWritingSock extends Thread {
    private Socket sockw;

    public TWritingSock(Socket sockw){
        this.sockw = sockw;
    }

    @Override
    public void run(){
        try {
            while(true){
                //Recuperation des saisies clavier
                BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

                //Ecriture de la saisie
                PrintWriter pw= new PrintWriter(sockw.getOutputStream(), true);

                String typed = br.readLine();
                if(typed.equals("fin")){
                    //sockw.close();
                    System.out.println("fermé");
                    break;
                }
                pw.write(typed);
            }           
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            try {
                sockw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    } 
}

public class TReadingSock extends Thread {
    private Socket sockr;

    public TReadingSock(Socket sockr){
        this.sockr = sockr;
    }

    @Override
    public void run(){
        try {
            while(true){
                BufferedReader br = new BufferedReader(new InputStreamReader(sockr.getInputStream()));
                String typed = br.readLine();
                if(typed.equals("fin")){
                    //sockr.close();
                    System.out.println("fermé");
                    break;
                }
                System.out.println(typed);
            }   
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            try {
                sockr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

【问题讨论】:

  • 你最好阅读套接字教程。
  • 是的,阅读教程,它并没有那么糟糕。

标签: java sockets


【解决方案1】:

(我将使用粗略和简单的图像来谈论 Socket,请把它看作是我试图尽可能简单地解释这一点。)

将 Socket 视为隧道。现在,如果我告诉你我的隧道尽头是 9998,那么你就可以到达它,但这条隧道的尽头可以是任何东西,由你决定。

ClientA(实际上是服务器)说“我想在端口 9998 上监听”。当 ClientA 连接时“好的,我们已连接,我在端口 9998,你在 50875。”。

ClientB 说“我想访问您的端口 9998,我将使用我的端口 50875 来实现。”

两个应用程序现在可以通过隧道进行通信,因为它们知道隧道的去向。

【讨论】:

  • 我选择了这个作为我的答案,尽管所有的解释都是清晰而有用的。结果我有点偏执,套接字工作正常,我的问题来自我曾经在流上操作的对象。
【解决方案2】:

Internet 上的每个 TCP 连接由两对或四个元素组成:端点 A IP 地址、端点 A 端口号和端点 B IP 地址、端点 B 端口。在传输层,地址在IP packet header 中指定,而端口在TCP header 中注明。这允许明确识别主机和进程(通过端口)以将数据包传递到。

当您bind() 您的侦听“服务器”套接字时,您修复了该端点端口号(在您的情况下为 9998)。当客户端连接到达时,其他三个部分也固定 - 您的本地 IP 是连接到达的网络接口,远程 IP 和端口是连接客户端的,其中端口通常由操作系统从ephemeral ports 的池,在您的示例中为 50875。

【讨论】:

    【解决方案3】:

    好的,让我试着让你更容易理解这些概念。因此,当您阅读教程时,一切都会变得有意义。

    套接字是非常简单的术语,是客户端和服务器之间的隧道。一个读,另一个写。换句话说,当一个等待读取时,另一个写入隧道。读取成功后,接收方即可处理数据。

    这里客户端和服务器都可以进行双向通信。有些人创建了一种锯齿形模式,服务器等待读取,客户端发送数据并进入读取等待,服务器处理它并响应客户端。客户端显示成功/错误。以此类推。

    在他们可以进行读写之前,他们形成了一个连接。为了建立连接,他们需要告诉对方他们的身份(IP 地址/DNS)是什么。

    到此为止了吗?

    如果您需要我解释端口,请告诉我。

    【讨论】:

      猜你喜欢
      • 2011-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-02
      • 2014-04-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多