我有一个java服务器(java 1.6,如果它有帮助)接受套接字连接,然后启动线程来解决它们,就像任何常规的多线程服务器一样。但我无法同时进行连接。我连接一个不断发送和接收消息的客户端,并尝试连接第二个,但第二个总是返回一个BindException告诉我该地址已被使用。我是否将整个多线程的内容弄错了,无论是在概念上还是在我的代码中?
我的服务器:
ServerSocket serverSocketUPMS1 = null;
try {
serverSocketUPMS1 = new ServerSocket(Integer.parseInt(cfg.getProperty("UPMSServerPort")));
serverSocketUPMS1.setSoTimeout(0);
log.info("Starting the USSDInterface server at port "+serverSocketUPMS1.getLocalPort());
} catch (IOException e) {
log.error("The TCP server couldn't be started",e);
finish = true;
}
while (!finish) {
try {
log.info("Waiting for a socket to connect...");
Socket subscriberSocket = serverSocketUPMS1.accept();
//Timeout de sesion ussd para poder crear una TimeoutException
int timeOutSocket = Integer.parseInt(cfg.getProperty("USSDSocketTimeout"));
log.info("New client arrived from " + subscriberSocket.getRemoteSocketAddress());
upms = new USSDSocket2(subscriberSocket,timeOutSocket);
Thread t1 = new Thread(upms);
t1.setName(Integer.toString(subscriberSocket.getLocalPort()) +","+ subscriberSocket.getRemoteSocketAddress() +", upms");
t1.start();
UPMSSimUtils.createAvailableInstance(upms);
log.trace("USSD Socket created and initiated");
}
catch (Exception e) {
log.warn("There's been an error while working with the server socket"+e.getMessage(), e);
try {
Thread.sleep(100);
} catch (InterruptedException e1) {
log.warn("There's been an error while waiting to resume the socket listenting"+e1.getMessage(), e1);
}
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
log.warn("There's been an error while waiting in the server"+e.getMessage(), e);
}
}
try {
serverSocketUPMS1.close();
log.info("TCP Server is now DOWN");
} catch (IOException e) {
log.error("There was an error while closing the server socket. TCP Server is now DOWN",e);
}
upms.stop();
处理线程:
public void run() {
new Thread(new Sender()).start();
while (!finish) {
byte buffer[] = new byte[10000];
byte size[] = new byte[4];
try {
this.socket.getInputStream().read(size, 0, 4);
Integer largo = calcularTamanio(size);
log.debug("Size in bytes: "+size);
log.debug("Length of the incoming string: " + largo);
this.socket.getInputStream().read(buffer, 0, largo);
log.debug("Buffer of the incoming string: " + tostr2(buffer));
decodeMessage(parseXML(toStr(buffer)), toStr(buffer));
} catch (SocketException e) {
log.error("Socket exception: " + e.getMessage(), e);
this.finish = true;
} catch (IOException e) {
log.error("IO exception: " + e.getMessage(), e);
this.finish = true;
} catch (JDOMException e) {
log.error("JDOM exception: " + e.getMessage(), e);
} catch (Exception e) {
log.error("Unknown exception: " + e.getMessage(), e);
this.finish = true;
}
// try {
// Thread.sleep(1);
// } catch (InterruptedException e) {
// log.error(e.getMessage(), e);
// }
}
try {
this.socket.close();
this.socketUDP.close();
} catch (IOException e) {
log.error("Error closing the sockets at the USSDSocket", e);
}
}
创建客户端套接字:
try{
socketsCreated++;
log.info("Attempting to create a socket");
Properties properties=Config.getInstance().getCfg();
ussdIface = new USSDInterfaceServerClass(properties);
int port=Integer.parseInt(properties.getProperty("TestClientSocketTargetPort"));
log.info("Client will connect to "+properties.getProperty("TestClientSocketTargetAddress")+":"+port);
clientSocket = new Socket(properties.getProperty("TestClientSocketTargetAddress"),port);
log.info("Socket connected");
log.info("Client socket targeting "+properties.getProperty("TestClientSocketTargetAddress")+":"+port+" created");
USSDSocket2 ussdSocket=new USSDSocket2(clientSocket,Integer.parseInt(properties.getProperty("USSDSocketTimeout")));
UPMSSimUtils.createAvailableInstance(ussdSocket);
upms = UPMSSimUtils.getAvailable(properties);
Thread t1 = new Thread(ussdSocket);
t1.setName("ussdsocket client test");
t1.start();
log.info("USSDSocket setted on the UPMSSimUtils");
USSDSocketClientThread socketClientThread=instance.new USSDSocketClientThread(upms, "ClientSocketThread-"+socketsCreated);
openSockets.add(socketClientThread);
new Thread(socketClientThread).start();
Thread.sleep(waitTimeBetweenConnections);
}catch(Throwable throwable){
log.warn("Error with a new connection",throwable);
socketsCreated--;
}
通过套接字发送数据的唯一功能:
public void send(String message) throws IOException {
log.info("Trying to send message "+message);
if (message != null && !"".equals(message)) {
int largo = message.length();
// largo = 800;
byte largobytes[] = new byte[4];
largobytes[0] = (byte) (largo % 256);
largobytes[1] = (byte) (largo / 256);
largobytes[2] = (byte) (largo & 0x00FF0000);
largobytes[3] = 0;
this.socket.getOutputStream().write(largobytes);
log.trace("Byte length sent: "+largobytes);
this.socket.getOutputStream().write(message.getBytes());
log.info("Message sent successfully");
}
}
处理线程负责读取通过套接字发送的所有内容。然后,decodeMessage创建一个响应,该响应在处理后通过同一个套接字发送。一个不同的实用类允许我通过引用它来发送消息,并引用它并等待它的响应。
我不知道它是否是我从输入/输出流中读取的方式或者是什么(使用普通流绑定或阻塞套接字?),但它确实如此令人烦恼的是,每一个例子似乎都告诉我,当它给我带来那些错误时,我所做的就是好的。
答案 0 :(得分:0)
忘掉一切。错误是代码的原始制造者在硬编码端口上启动了硬编码套接字。由于套接字没有被使用,我从未注意到它的存在(我错误地认为错误的堆栈跟踪导致实际工作套接字,但事实并非如此)