在服务器套接字上接受来自客户端的多个连接
Accepting multiple connections from clients on a serversocket
我刚开始使用套接字,对于我当前的项目,我需要能够从客户端控制我的程序,但是如果我的项目合作伙伴想要同时使用他的客户端,服务器不会发送他 "You are connected" 消息,如连接 class 中所示。所以我假设服务器不会同时接受多个客户端。我曾尝试使用 class 连接的线程,但也不会将消息 "You are connected" 发送到第二个客户端。我在这里做错了什么?
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Listener extends Thread{
private ServerSocket server;
private int PORT;
public boolean running;
public Listener(int port){
try{
this.PORT = port;
this.server = new ServerSocket(PORT,10);
}catch (IOException e) {
System.out.println("Could not create serverSocket...");
}
}
@Override
public void run() {
this.running = true;
try{
waitForConnection();
}catch(IOException e){
System.out.println("Could not accept connection request..");
run();
}
}
public void dispose(){
try{
System.out.println("DISPOSE");
running = false;
server.close();
} catch (IOException i) {
System.out.println("Could not close ServerSocket");
}
}
private void waitForConnection() throws IOException{
while(running){
System.out.println("Waiting for connection");
Socket client = server.accept();
Runnable connection = new Connection(client);
new Thread(connection).start();
}
}
}
这是我用来让多个用户同时连接的线程:
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
public class Connection extends Thread {
Socket connection;
private ObjectOutputStream output;
private ObjectInputStream input;
private boolean running;
public Connection(Socket connect){
this.connection = connect;
try {
setupStreams();
whileListening();
} catch (IOException e) {
System.out.println("could not connect to: "+ connection.getInetAddress().getHostName());
}
}
public void dispose(){
try{
output.close();
input.close();
connection.close();
running = false;
}catch(IOException ioException){
ioException.printStackTrace();
}
}
private void whileListening(){
String message = "You are connected! ";
sendMessage(message);
do{
try{
message = (String) input.readObject();
checkMessage(message);
}catch(ClassNotFoundException classNotFoundException){
sendMessage("tf did you send? ");
}catch (IOException e) {
dispose();
run();
}
}while(!message.equals("Client - END") && running == true);
}
private void setupStreams() throws IOException{
output = new ObjectOutputStream(connection.getOutputStream());
output.flush();
input = new ObjectInputStream(connection.getInputStream());
}
private void sendMessage(String message){
try {
output.writeObject("Server - " + message+"\n");
output.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
private void checkMessage(String text){
//check the message
}
}
编辑:附加信息
在第一个客户端连接之前,服务器控制台显示 "Waiting for connection",然后当第一个客户端连接时,客户端控制台显示 "You are connected",当第二个客户端连接时,控制台为黑色,当我关闭第一个客户端时,第二个客户端控制台显示 "You are connected",服务器控制台显示 "Waiting for connection",然后如果我也关闭第二个客户端,服务器控制台再次显示 "Waiting for connection"。
我想你必须先接受,然后你才开始跟帖。
例如,让我们假设这样的事情
- 在您的主 class 中,您获得了 ServerSocketFactory,然后是 ServerSocket。
- 然后,在(无休止的)循环中,您等待 ServerSocket.accept()
返回的新套接字
- 只有在那之后,你才能开始你的话题
这是来自 SSLServerSocket 的示例,其逻辑几乎相同(将其视为 pseudo-code)
SSLContext sc = SSLContext.getInstance("TLS");
(...)
SSLServerSocketFactory ssf = sc.getServerSocketFactory();
SSLServerSocket s = (SSLServerSocket) ssf.createServerSocket(portNumber);
while (listening) {
SSLSocket c = (SSLSocket) s.accept();
log.info("Serving");
new SimpleSSLServerSocketThread(c).start();
}
在 public class Connection extends Thread
的构造函数中执行此 whileListening()
操作,因此构造函数永远不会结束,您需要覆盖 run()
函数并在那里执行此操作
@Override
public void run() {
while(true) {
try {
whileListening();
} catch(Exception e) {}
}
}
像这样,它应该可以解决问题。
我刚开始使用套接字,对于我当前的项目,我需要能够从客户端控制我的程序,但是如果我的项目合作伙伴想要同时使用他的客户端,服务器不会发送他 "You are connected" 消息,如连接 class 中所示。所以我假设服务器不会同时接受多个客户端。我曾尝试使用 class 连接的线程,但也不会将消息 "You are connected" 发送到第二个客户端。我在这里做错了什么?
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Listener extends Thread{
private ServerSocket server;
private int PORT;
public boolean running;
public Listener(int port){
try{
this.PORT = port;
this.server = new ServerSocket(PORT,10);
}catch (IOException e) {
System.out.println("Could not create serverSocket...");
}
}
@Override
public void run() {
this.running = true;
try{
waitForConnection();
}catch(IOException e){
System.out.println("Could not accept connection request..");
run();
}
}
public void dispose(){
try{
System.out.println("DISPOSE");
running = false;
server.close();
} catch (IOException i) {
System.out.println("Could not close ServerSocket");
}
}
private void waitForConnection() throws IOException{
while(running){
System.out.println("Waiting for connection");
Socket client = server.accept();
Runnable connection = new Connection(client);
new Thread(connection).start();
}
}
}
这是我用来让多个用户同时连接的线程:
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
public class Connection extends Thread {
Socket connection;
private ObjectOutputStream output;
private ObjectInputStream input;
private boolean running;
public Connection(Socket connect){
this.connection = connect;
try {
setupStreams();
whileListening();
} catch (IOException e) {
System.out.println("could not connect to: "+ connection.getInetAddress().getHostName());
}
}
public void dispose(){
try{
output.close();
input.close();
connection.close();
running = false;
}catch(IOException ioException){
ioException.printStackTrace();
}
}
private void whileListening(){
String message = "You are connected! ";
sendMessage(message);
do{
try{
message = (String) input.readObject();
checkMessage(message);
}catch(ClassNotFoundException classNotFoundException){
sendMessage("tf did you send? ");
}catch (IOException e) {
dispose();
run();
}
}while(!message.equals("Client - END") && running == true);
}
private void setupStreams() throws IOException{
output = new ObjectOutputStream(connection.getOutputStream());
output.flush();
input = new ObjectInputStream(connection.getInputStream());
}
private void sendMessage(String message){
try {
output.writeObject("Server - " + message+"\n");
output.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
private void checkMessage(String text){
//check the message
}
}
编辑:附加信息
在第一个客户端连接之前,服务器控制台显示 "Waiting for connection",然后当第一个客户端连接时,客户端控制台显示 "You are connected",当第二个客户端连接时,控制台为黑色,当我关闭第一个客户端时,第二个客户端控制台显示 "You are connected",服务器控制台显示 "Waiting for connection",然后如果我也关闭第二个客户端,服务器控制台再次显示 "Waiting for connection"。
我想你必须先接受,然后你才开始跟帖。
例如,让我们假设这样的事情
- 在您的主 class 中,您获得了 ServerSocketFactory,然后是 ServerSocket。
- 然后,在(无休止的)循环中,您等待 ServerSocket.accept() 返回的新套接字
- 只有在那之后,你才能开始你的话题
这是来自 SSLServerSocket 的示例,其逻辑几乎相同(将其视为 pseudo-code)
SSLContext sc = SSLContext.getInstance("TLS");
(...)
SSLServerSocketFactory ssf = sc.getServerSocketFactory();
SSLServerSocket s = (SSLServerSocket) ssf.createServerSocket(portNumber);
while (listening) {
SSLSocket c = (SSLSocket) s.accept();
log.info("Serving");
new SimpleSSLServerSocketThread(c).start();
}
在 public class Connection extends Thread
的构造函数中执行此 whileListening()
操作,因此构造函数永远不会结束,您需要覆盖 run()
函数并在那里执行此操作
@Override
public void run() {
while(true) {
try {
whileListening();
} catch(Exception e) {}
}
}
像这样,它应该可以解决问题。