我是Java和JavaFX的新手,所以请原谅我的新手问题。在过去的几天里,我一直在寻找我正在努力做的事情的例子,但是没有找到任何答案。下面是我正在尝试做的:我试图创建一个简单的javafx GUI客户端套接字应用程序,使用场景生成器连接到服务器并发送/接收数据。很简单,但是当我试图在JavaFX中实现它时,我的图形用户界面冻结了。我研究发现,原因是套接字通信占用了所有的时间,javafx GUI无法更新。我的研究告诉我如何使用任务。所以,我创建了一个简单的应用程序,它创建一个任务,连接到一个互联网套接字(端口80),发送命令“GET/HTTP/1.1\r\n\r\n”,该命令将请求页面,然后打印出收到的每一行。问题是,我想一遍又一遍地(每3秒钟)这样做。任务成功运行一次,但随后停止。在下面的代码中,将线程置于Hibernate状态的行永远不会到达,但是打印任何错误的行也不会发送到system.out。
这是控制器代码
package clientSocketExample;
import java.io.*;
import java.net.*;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.concurrent.Task;
/**
* Controller class of the HelloWorld sample.
*/
public class ClientSocketExampleController implements Initializable
{
@FXML
Button button;
private boolean keepRunning = true;
/**
* Initializes the controller class.
*/
@Override
public void initialize(URL url, ResourceBundle rsrcs)
{
if (button != null)
{
button.setOnAction(new EventHandler<ActionEvent>()
{
@Override
public void handle(ActionEvent event)
{
keepRunning = false;
System.out.println("Hello World\n");
}
});
}
// Create a background task to handle the Client-Server socket
// This is needed because JavaFX is not thread safe
Task<Integer> task = new Task<Integer>()
{
@Override
protected Integer call() throws Exception
{
Socket s = new Socket();
// String host = "www.google.com";
// String host = "www.amazon.com";
String host = "www.yahoo.com";
PrintWriter s_out = null;
BufferedReader s_in = null;
int lineNums = 0;
try
{
s.connect(new InetSocketAddress(host, 80));
System.out.println("Connected\n");
// Create writer for socket
s_out = new PrintWriter(s.getOutputStream(), true);
// Create reader for socket
s_in = new BufferedReader(new InputStreamReader(s.getInputStream()));
}
catch (IOException e)
{
// Host not found, so print error
System.err.println("Don't know about host : " + host);
System.exit(1);
}
// Loop forever waiting for task to be cancelled
while (isCancelled() == false)
{
// Send message to server
String message = "GET / HTTP/1.1\r\n\r\n";
s_out.println(message);
System.out.println("Message sent\n");
// Get response from server
try
{
String response;
while ((response = s_in.readLine()) != null)
{
System.out.print("Line #: "+lineNums+" ");
System.out.println(response);
lineNums++;
}
} catch (IOException e)
{
System.err.println("Couldn't get response from host");
}
System.out.println("Thread going to sleep\n\n\n");
Thread.sleep(3000);
System.out.println("Thread waking up from sleep\n\n\n");
} // End while
return lineNums;
}
}; // End Initialize
// start the background task
Thread th = new Thread(task);
th.setDaemon(true);
System.out.println("Starting background task...");
th.start();
}
}`
主要的。java类如下所示:
package clientSocketExample;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
public class Main extends Application
{
/**
* @param args the command line arguments
*/
public static void main(String[] args)
{
Application.launch(Main.class, (java.lang.String[]) null);
}
@Override
public void start(Stage primaryStage)
{
try
{
AnchorPane page = (AnchorPane) FXMLLoader.load(Main.class
.getResource("ClientSocketExample.fxml"));
Scene scene = new Scene(page);
primaryStage.setScene(scene);
primaryStage.setTitle("Hello World Sample");
primaryStage.show();
} catch (Exception ex)
{
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
###
最后,FXML文件如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>
<AnchorPane id="AnchorPane" prefHeight="365.0" prefWidth="378.0" xmlns:fx="http://javafx.com/fxml" fx:controller="clientSocketExample.ClientSocketExampleController">
<children>
<Button fx:id="button" layoutX="147.0" layoutY="28.0" text="Connect" />
<TitledPane animated="false" layoutY="159.0" prefWidth="378.0" text="Received Data">
<content>
<AnchorPane id="Content" minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children>
<TextArea fx:id="textAreaField" prefHeight="180.0" prefWidth="374.0" wrapText="true" />
</children>
</AnchorPane>
</content>
</TitledPane>
</children>
</AnchorPane>
提前感谢你的帮助,韦恩
根据你的要求,有几件事需要改变:
>
将此插入您的请求中
"\r\nHost: <host>\r\nConnection: keep-alive"
这将确保服务器在响应您的请求后不会关闭您的连接。
将你的虽然循环更改为:
while (s_in.ready() && (response = s_in.readLine()) != null)
这将确保从BufferedReader中读取内容。查看以下帖子,了解BufferedReader将挂起的原因:https://stackoverflow.com/a/7855911/1359765和https://stackoverflow.com/a/15510821/1359765
Gui冻结的问题是,它是连接到套接字的“控制器”类。当我使用JavaFx和JavaFx场景生成器创建自己的聊天程序时,我也遇到了同样的问题。
你可以做两件事:
>
创建一个新类(SocketConnector()
)将您连接到套接字。
连接到主类中的套接字,而不是controller
不管你不能连接到你的控制器类中的套接字,我很抱歉,我不能详细描述为什么你不能。我只知道我经历了好几次这个问题,这就是解决它的方法!
这是我的客户端和服务器的代码。 class Client1{Client1(int no){try{String message;message=“Hello this is client”+no;byte[]b=message.getBytes();DatagramPacket dp=new DatagramPacket(b,b length,inetAddress.getLocalHost()
问题内容: 我正在使用Java套接字构建一个简单的客户端/服务器应用程序,并尝试使用ObjectOutputStream等。 我一直在这个URL http://java.sun.com/developer/technicalArticles/ALT/sockets上关注该教程,当它谈到通过套接字传输对象时,它从一半开始。 请参阅我为客户端提供的代码http://pastebin.com/m37e4
套接字编程在本系列教程中地位并不是很突出,但是我们观察网络应用,绝大多数都是基于Socket来做的,哪怕是绝大多数的木马程序也是如此。官方关于socket编程的文档地址为https://docs.python.org/2/library/socket.html,我承认我看起来都很费劲。 套接字为BSD UNIX系统核心的一部分,而且他们也被许多其他类似UNIX的操作系统包括Linux所采纳。许多非
什么是套接字? Socket是一种Berkeley UNIX机制,用于在不同进程之间创建虚拟双工连接。 随后将其移植到每个已知的OS上,使得能够跨越在不同OS软件上运行的地理位置的系统之间进行通信。 如果不是套接字,系统之间的大多数网络通信永远不会发生。 仔细看看; 网络上的典型计算机系统根据其上运行的各种应用程序接收和发送信息。 此信息被路由到系统,因为为其指定了唯一的IP地址。 在系统上,此信
This chapter looks at the basic techniques for network programming. It deals with host and service addressing, and then considers TCP and UDP. It shows how to build both servers and clients using the
计算机网络基础 ip地址 为了使网络上的计算机能够彼此识别对方,每台计算机都需要一个IP地址以标识自己。 IPv4:32位,IPv6:64位 OSI七层参考模型 应用层 表示层 会话层 传输层 网络层 数据链路层 物理层 地址解析 地址解析是指将计算机的协议地址解析为物理地址,即MAC(Medium Access Control)地址,又称为媒体访问控制地址。通常,在网络上由地址解析协议(ARP)