Java 使用网络服务器部署OSGI捆绑包时的无限循环
我正在尝试用使用网络套接字的网络服务器实现OSGI捆绑包。 这是完整的源代码: 这是激活剂:Java 使用网络服务器部署OSGI捆绑包时的无限循环,java,networking,maven,network-programming,glassfish,Java,Networking,Maven,Network Programming,Glassfish,我正在尝试用使用网络套接字的网络服务器实现OSGI捆绑包。 这是完整的源代码: 这是激活剂: package org.DX_57.osgi.CB_27.impl; import java.util.Properties; import org.DX_57.osgi.CB_27.api.CBridge; import org.DX_57.osgi.CB_27.impl.EchoServer; import org.osgi.framework.BundleActivator; import or
package org.DX_57.osgi.CB_27.impl;
import java.util.Properties;
import org.DX_57.osgi.CB_27.api.CBridge;
import org.DX_57.osgi.CB_27.impl.EchoServer;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
public class CBridgeApp implements BundleActivator {
public void start(BundleContext bc) throws Exception {
ServiceRegistration registerService = bc.registerService(CBridge.class.getName(), new CBridgeImpl(), new Properties());
EchoServer();
}
public void stop(BundleContext bc) throws Exception {
boolean ungetService = bc.ungetService(bc.getServiceReference(CBridge.class.getName()));
}
private void EchoServer() {
EchoServer method = new EchoServer();
}
}
这是Java网络服务器的源代码:
package org.DX_57.osgi.CB_27.impl;
import java.net.*;
import java.io.*;
public class EchoServer
{
ServerSocket m_ServerSocket;
public EchoServer()
{
try
{
// Create the server socket.
m_ServerSocket = new ServerSocket(12111);
}
catch(IOException ioe)
{
System.out.println("Could not create server socket at 12111. Quitting.");
System.exit(-1);
}
System.out.println("Listening for clients on 12111...");
// Successfully created Server Socket. Now wait for connections.
int id = 0;
while(true)
{
try
{
// Accept incoming connections.
Socket clientSocket = m_ServerSocket.accept();
// accept() will block until a client connects to the server.
// If execution reaches this point, then it means that a client
// socket has been accepted.
// For each client, we will start a service thread to
// service the client requests. This is to demonstrate a
// multithreaded server, although not required for such a
// trivial application. Starting a thread also lets our
// EchoServer accept multiple connections simultaneously.
// Start a service thread
ClientServiceThread cliThread = new ClientServiceThread(clientSocket, id++);
cliThread.start();
}
catch(IOException ioe)
{
System.out.println("Exception encountered on accept. Ignoring. Stack Trace :");
ioe.printStackTrace();
}
}
}
public static void main (String[] args)
{
new EchoServer();
}
class ClientServiceThread extends Thread
{
Socket m_clientSocket;
int m_clientID = -1;
boolean m_bRunThread = true;
ClientServiceThread(Socket s, int clientID)
{
m_clientSocket = s;
m_clientID = clientID;
}
public void run()
{
// Obtain the input stream and the output stream for the socket
// A good practice is to encapsulate them with a BufferedReader
// and a PrintWriter as shown below.
BufferedReader in = null;
PrintWriter out = null;
// Print out details of this connection
System.out.println("Accepted Client : ID - " + m_clientID + " : Address - " +
m_clientSocket.getInetAddress().getHostName());
try
{
in = new BufferedReader(new InputStreamReader(m_clientSocket.getInputStream()));
out = new PrintWriter(new OutputStreamWriter(m_clientSocket.getOutputStream()));
// At this point, we can read for input and reply with appropriate output.
// Run in a loop until m_bRunThread is set to false
while(m_bRunThread)
{
// read incoming stream
String clientCommand = in.readLine();
System.out.println("Client Says :" + clientCommand);
if(clientCommand.equalsIgnoreCase("quit"))
{
// Special command. Quit this thread
m_bRunThread = false;
System.out.print("Stopping client thread for client : " + m_clientID);
}
else
{
// Echo it back to the client.
out.println(clientCommand);
out.flush();
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
// Clean up
try
{
in.close();
out.close();
m_clientSocket.close();
System.out.println("...Stopped");
}
catch(IOException ioe)
{
ioe.printStackTrace();
}
}
}
}
}
当我尝试在Glassfish服务器上部署捆绑包时,应用程序服务器挂起,但我可以使用java客户端连接到java网络服务器。似乎有一个无限循环。我需要帮助来修复代码
最好的祝愿您的bundle activator start方法永远不会返回,因为您正在使用无限循环调用服务的构造函数。一个好的做法是尽可能快地从束激活器返回 下面是一个如何重写代码的想法:
public class EchoServer {
private volatile boolean started;
public void start() {
new Thread(new Runnable() {
@Override
public void run() {
started = true;
try {
m_ServerSocket = new ServerSocket(12111);
} catch(IOException ioe) {
System.out.println("Could not create server socket at 12111. Quitting.");
System.exit(-1);
}
System.out.println("Listening for clients on 12111...");
// Successfully created Server Socket. Now wait for connections.
int id = 0;
while (started) {
try {
Socket clientSocket = m_ServerSocket.accept();
ClientServiceThread cliThread = new ClientServiceThread(clientSocket, id++);
cliThread.start();
} catch(IOException ioe) {
System.out.println("Exception encountered on accept. Ignoring. Stack Trace :");
ioe.printStackTrace();
}
}
}
}).start();
}
public void stop() {
started = false;
}
}
活化剂
public class CBridgeApp implements BundleActivator {
private EchoServer method;
public void start(BundleContext bc) throws Exception {
...
method = new EchoServer();
method.start();
}
public void stop(BundleContext bc) throws Exception {
...
method.stop();
}
}
回答得很好。我不理解代码的某些部分。您是否可以添加缺少的(…)部分?谢谢。在bundle activator中,最好由您决定应该添加哪些缺少的部件,因为我不明白您为什么需要在那里获取并取消设置CBridge的服务引用。该服务已更新,但我没有检查是否可以编译。好消息是我可以编译代码,并且可以成功地将其上传到Glassfish上。java网络客户端可以成功地与服务器通信。坏消息是,当我取消部署包并再次部署它时,Glassfish服务器崩溃。这是错误日志:无法创建套接字。可能旧的套接字连接没有清理?您必须关闭ServerSocket。这可以在EchoServer.stop()方法中完成。是的,我这样修改了代码:现在它可以工作了,Glassfish没有崩溃。剩下的一件事是:当我取消部署包时,客户端可以再次连接一次。这意味着我认为插座没有关闭。然后我尝试再次连接,连接冻结。我想插座没有关上或清洁。我需要在运行stop()方法时关闭套接字。我需要修改代码的某些部分,并使某些部分像IN和OUT一样可见。我怎么能做到?我尝试过,但在stop()方法中看不到它们。