我首先使用线程和套接字,所以我正在尝试聊天(本地)
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对象,我将它传递给我的线程,以便他们可以完成自己的工作。这是针对ClientA的。客户端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();
}
}
}
}
答案 0 :(得分:2)
(我将使用原始和简单的图像来讨论Socket,请将其视为我尝试尽可能简单地解释它。)
将Socket视为隧道。现在,如果我告诉你隧道的末端是9998,你就可以到达它,但是这条隧道的终点可以是任何东西,由你决定。
ClientA(实际上是服务器),正在说“我想收听端口9998”。当ClientA连接“Ok我们已连接时,我在端口9998上,而你在50875上。”。
ClientB说“我想要到达您的端口9998,我将使用我的端口50875这样做。”
两个应用程序现在都可以通过隧道进行通信,因为它们知道它的去向。
答案 1 :(得分:1)
Internet上的每个TCP连接由两对或四个元素组成:端点A IP地址,端点A端口号和端点B IP地址,端点B端口。在传输级别,地址在IP packet header中指定,而端口在TCP header中注明。这允许明确识别主机和进程(通过端口)来传送数据包。
当您bind()
监听“服务器”套接字时,您可以修复该端点端口号(在您的情况下为9998)。当客户端连接到达时,其他三个部分也是固定的 - 您的本地IP是连接到达的网络接口,远程IP和端口是连接客户端,其中端口通常由操作系统从您的示例中的ephemeral ports池,50875。
答案 2 :(得分:0)
好的,让我试着让你理解这些概念很简单。因此,当您阅读本教程时,它将是有意义的。
套接字是非常简单的术语,是客户端和服务器之间的隧道。当一个人读,另一个人写。换句话说,当一个人等待阅读时,另一个人写入隧道。当读取成功时,接收器可以处理数据。
这里客户端和服务器都可以进行双向通信。有些人创建一个Z字形的模式,服务器等待读取,客户端发送数据并进入读取等待,服务器处理它并响应客户端。客户端显示成功/错误。等等。
在他们进行读写之前,他们会形成一个连接。为了形成连接,他们需要告诉对方他们的身份(IP地址/ DNS)是什么。
到目前为止?
如果您需要我解释端口,请告诉我。