【发布时间】:2017-05-30 07:11:48
【问题描述】:
我正在尝试在我的 Spring Boot 应用程序中实现 TCP 服务器和客户端。 最初,我的控制器从另一个应用程序接收响应,在收到此响应时,我的服务类调用另一个方法来建立 tcp 连接。建立 tcp 连接后,我调用一个设置 tcp 客户端的方法。 TCP 服务器不断侦听来自已建立连接的机器的消息,并根据消息名称执行各种操作。每次执行代码时,都会出现以下错误:
java.net.BindException: Address already in use: JVM_Bind
at java.net.DualStackPlainSocketImpl.bind0(Native Method)
at java.net.DualStackPlainSocketImpl.socketBind(DualStackPlainSocketImpl.java:106)
at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:387)
at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:190)
at java.net.ServerSocket.bind(ServerSocket.java:375)
at java.net.ServerSocket.<init>(ServerSocket.java:237)
at java.net.ServerSocket.<init>(ServerSocket.java:128)
at com.epbRestServer.tcp.TCPServer.setupTCPConnection(TCPServer.java:24)
at com.epbRestServer.service.impl.EPBRestServerServiceImpl.handleStartEPC(EPBRestServerServiceImpl.java:28)
at com.epbRestServer.controller.EPBRestServerController.startEPC(EPBRestServerController.java:27)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:114)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:661)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:87)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
调用tcp客户端和tcp服务器方法的代码:
public ResponseBean handleStartEPC(RequestBean request) {
// Code for establishing tcp connection
ResponseBean response = new ResponseBean();
if (request != null) {
TCPServer tcpServer = new TCPServer();
response = tcpServer.setupTCPConnection(request);
if (response.getTcpConnect()) {
TCPClient tcpClient = new TCPClient();
TCPRequestBean tcpBean = new TCPRequestBean();
String str = new String();
str = str.concat("IP:").concat(request.getIpAddress()).concat(",NodeName:").concat(request.getVduName())
.concat(",Interface:").concat(request.getInterfaceName());
int length = str.length();
str = "Length:" + length +"," + str;
tcpBean.setIpAddress(request.getIpAddress());
tcpBean.setInputData(str);
response = tcpClient.setupTCPClient(tcpBean);
}
else {
response.setStatus("FAILURE");
}
}
else {
response.setStatus("FAILURE");
}
return response;
}
tcp客户端和tcp服务器的代码
public class TCPServer {
@Autowired
EPBRestServerService epbRestServerService;
public ResponseBean setupTCPConnection(RequestBean request) {
ResponseBean response = new ResponseBean();
try {
ServerSocket server = new ServerSocket(8000);
Socket s = server.accept();// establishes connection
DataInputStream dis = new DataInputStream(s.getInputStream());
String str = (String) dis.readUTF();
VNFNotificationRequestBean vnfRequestBean = new VNFNotificationRequestBean();
System.out.println("message:" + str);
switch (str.toLowerCase()) {
case "restAPIResponse":
response.setTcpConnect(true);
response.setStatus("SUCCESS");
break;
case "startsuccess":
vnfRequestBean.setEvent("StartSuccess");
vnfRequestBean.setSystemId(request.getSystemId());
vnfRequestBean.setContent("ContentType - application/json");
response = epbRestServerService.triggerEvent(request, vnfRequestBean);
break;
case "initsuccess":
vnfRequestBean.setEvent("InitSuccess");
vnfRequestBean.setSystemId(request.getSystemId());
vnfRequestBean.setContent("ContentType - application/json");
response = epbRestServerService.triggerEvent(request, vnfRequestBean);
break;
case "configuresuccess":
vnfRequestBean.setEvent("ConfigureSuccess");
vnfRequestBean.setSystemId(request.getSystemId());
vnfRequestBean.setContent("ContentType - application/json");
response = epbRestServerService.triggerEvent(request, vnfRequestBean);
break;
default:
response.setStatus("FAILURE");
break;
}
server.close();
} catch (IOException e) {
response.setTcpConnect(false);
e.printStackTrace();
}
return response;
}
public class TCPClient {
public ResponseBean setupTCPClient(TCPRequestBean request) {
ResponseBean response = new ResponseBean();
try {
Socket s = new Socket(request.getIpAddress(), 8000);
DataOutputStream dout = new DataOutputStream(s.getOutputStream());
dout.writeUTF(request.getInputData());
dout.flush();
dout.close();
s.close();
response.setStatus("SUCCESS");
} catch (IOException e) {
System.out.println(e);
response.setStatus("FAILURE");
}
return response;
}
}
【问题讨论】:
-
某些东西已经在使用端口 8000 - 使用 netstat 或其他一些工具来解决这个问题。它甚至可以是你自己的代码?
-
@ScaryWombat 是的,看来我自己的代码正在使用这个端口。这里的问题是我的代码无法与这台机器建立连接。
-
您应该在每次应用程序执行时设置一次
ServerSocket,而不是每次StartEPC事件设置一次。但由于您似乎是您自己的进程内服务器的客户端,因此很难看出使用 TCP 的意义。 -
已经有一个 jvm 在
8000端口上运行,所以如果你尝试在同一个端口上运行同一个应用程序,spring-boot将无法启动。我觉得你有三个选择。 1) 根据您的操作系统运行netstat命令,找出process-id并终止。 2) 尝试在不同的端口上运行 spring-boot 应用程序。您可以通过更改application.properties文件来实现此目的,spring-boot将尝试在该端口上启动。 3)如果是你的本地机器,你可以保存你的工作并重新启动。这应该会终止在8000端口上运行的进程。希望这会有所帮助,祝你好运! -
谢谢大家。我将我的代码从先设置服务器更改为先设置客户端,然后它工作了。