我使用这个(Android TCP连接增强的)教程来创建简单的JAVA TCPServer和Android TCPClient。它工作得很好,但使用这段代码我只能同时将一个设备连接到服务器。我必须更改什么才能连接多个设备?
public class Constants {
public static final String CLOSED_CONNECTION = "kazy_closed_connection";
public static final String LOGIN_NAME = "kazy_login_name";
}
public class MainScreen extends JFrame {
/**
*
*/
private static final long serialVersionUID = 8399514248326995812L;
private JTextArea messagesArea;
private JButton sendButton;
private JTextField message;
private JButton startServer;
private JButton stopServer;
private TcpServer mServer;
public MainScreen() {
super("MainScreen");
JPanel panelFields = new JPanel();
panelFields.setLayout(new BoxLayout(panelFields, BoxLayout.X_AXIS));
JPanel panelFields2 = new JPanel();
panelFields2.setLayout(new BoxLayout(panelFields2, BoxLayout.X_AXIS));
// here we will have the text messages screen
messagesArea = new JTextArea();
messagesArea.setColumns(30);
messagesArea.setRows(10);
messagesArea.setEditable(false);
sendButton = new JButton("Send");
sendButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// get the message from the text view
String messageText = message.getText();
// add message to the message area
messagesArea.append("\n" + messageText);
if (mServer != null) {
// send the message to the client
mServer.sendMessage(messageText);
}
// clear text
message.setText("");
}
});
startServer = new JButton("Start");
startServer.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// creates the object OnMessageReceived asked by the TCPServer
// constructor
mServer = new TcpServer(new TcpServer.OnMessageReceived() {
@Override
// this method declared in the interface from TCPServer
// class is implemented here
// this method is actually a callback method, because it
// will run every time when it will be called from
// TCPServer class (at while)
public void messageReceived(String message) {
messagesArea.append("\n " + message);
}
});
mServer.start();
// disable the start button and enable the stop one
startServer.setEnabled(false);
stopServer.setEnabled(true);
}
});
stopServer = new JButton("Stop");
stopServer.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (mServer != null) {
mServer.close();
}
// disable the stop button and enable the start one
startServer.setEnabled(true);
stopServer.setEnabled(false);
}
});
// the box where the user enters the text (EditText is called in
// Android)
message = new JTextField();
message.setSize(200, 20);
// add the buttons and the text fields to the panel
panelFields.add(messagesArea);
panelFields.add(startServer);
panelFields.add(stopServer);
panelFields2.add(message);
panelFields2.add(sendButton);
getContentPane().add(panelFields);
getContentPane().add(panelFields2);
getContentPane().setLayout(
new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
setSize(300, 170);
setVisible(true);
}
}
public class TcpServer extends Thread {
public static final int SERVERPORT = 4444;
// while this is true the server will run
private boolean running = false;
// used to send messages
private PrintWriter bufferSender;
// callback used to notify new messages received
private OnMessageReceived messageListener;
private ServerSocket serverSocket;
private Socket client;
/**
* Constructor of the class
*
* @param messageListener
* listens for the messages
*/
public TcpServer(OnMessageReceived messageListener) {
this.messageListener = messageListener;
}
public static void main(String[] args) {
// opens the window where the messages will be received and sent
MainScreen frame = new MainScreen();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
/**
* Close the server
*/
public void close() {
running = false;
if (bufferSender != null) {
bufferSender.flush();
bufferSender.close();
bufferSender = null;
}
try {
client.close();
serverSocket.close();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("S: Done.");
serverSocket = null;
client = null;
}
/**
* Method to send the messages from server to client
*
* @param message
* the message sent by the server
*/
public void sendMessage(String message) {
if (bufferSender != null && !bufferSender.checkError()) {
bufferSender.println(message);
bufferSender.flush();
}
}
public boolean hasCommand(String message) {
if (message != null) {
if (message.contains(Constants.CLOSED_CONNECTION)) {
messageListener.messageReceived(message.replaceAll(
Constants.CLOSED_CONNECTION, "")
+ " disconnected");
// close the server connection if we have this command and
// rebuild a new one
close();
runServer();
return true;
} else if (message.contains(Constants.LOGIN_NAME)) {
messageListener.messageReceived(message.replaceAll(
Constants.LOGIN_NAME, "") + " connected");
return true;
}
}
return false;
}
/**
* Builds a new server connection
*/
private void runServer() {
running = true;
try {
System.out.println("S: Connecting...");
// create a server socket. A server socket waits for requests to
// come in over the network.
serverSocket = new ServerSocket(SERVERPORT);
// create client socket... the method accept() listens for a
// connection to be made to this socket and accepts it.
client = serverSocket.accept();
System.out.println("S: Receiving...");
try {
// sends the message to the client
bufferSender = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(client.getOutputStream())), true);
// read the message received from client
BufferedReader in = new BufferedReader(new InputStreamReader(
client.getInputStream()));
// in this while we wait to receive messages from client (it's
// an infinite loop)
// this while it's like a listener for messages
while (running) {
String message = null;
try {
message = in.readLine();
} catch (IOException e) {
System.out.println("Error reading message: "
+ e.getMessage());
}
if (hasCommand(message)) {
continue;
}
if (message != null && messageListener != null) {
// call the method messageReceived from ServerBoard
// class
messageListener.messageReceived(message);
}
}
} catch (Exception e) {
System.out.println("S: Error");
e.printStackTrace();
}
} catch (Exception e) {
System.out.println("S: Error");
e.printStackTrace();
}
}
@Override
public void run() {
super.run();
runServer();
}
// Declare the interface. The method messageReceived(String message) will
// must be implemented in the ServerBoard
// class at on startServer button click
public interface OnMessageReceived {
public void messageReceived(String message);
}
}
public class TCPClient {
public static final String SERVER_IP = "192.168.0.102"; // your computer IP
// address
public static final int SERVER_PORT = 4444;
// message to send to the server
private String mServerMessage;
// sends message received notifications
private OnMessageReceived mMessageListener = null;
// while this is true, the server will continue running
private boolean mRun = false;
// used to send messages
private PrintWriter mBufferOut;
// used to read messages from the server
private BufferedReader mBufferIn;
private String uid;
/**
* Constructor of the class. OnMessagedReceived listens for the messages
* received from server
*/
public TCPClient(OnMessageReceived listener) {
mMessageListener = listener;
}
/**
* Sends the message entered by client to the server
*
* @param message
* text entered by client
*/
public void sendMessage(String message) {
if (mBufferOut != null && !mBufferOut.checkError()) {
mBufferOut.println(message);
mBufferOut.flush();
}
}
/**
* Close the connection and release the members
*/
public void stopClient() {
// send mesage that we are closing the connection
TelephonyManager tManager = (TelephonyManager) MyApplication.getInstance().getSystemService(Context.TELEPHONY_SERVICE);
uid = tManager.getDeviceId();
sendMessage(Constants.CLOSED_CONNECTION + "id: " + uid);
mRun = false;
if (mBufferOut != null) {
mBufferOut.flush();
mBufferOut.close();
}
mMessageListener = null;
mBufferIn = null;
mBufferOut = null;
mServerMessage = null;
}
public void run() {
mRun = true;
try {
// here you must put your computer's IP address.
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
MyLog.e("TCP Client", "C: Connecting...");
// create a socket to make the connection with the server
Socket socket = new Socket(serverAddr, SERVER_PORT);
try {
// sends the message to the server
mBufferOut = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())), true);
// receives the message which the server sends back
mBufferIn = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
// send login name
TelephonyManager tManager = (TelephonyManager) MyApplication.getInstance().getSystemService(Context.TELEPHONY_SERVICE);
uid = tManager.getDeviceId();
sendMessage(Constants.LOGIN_NAME + "id: " + uid);
// in this while the client listens for the messages sent by the
// server
while (mRun) {
mServerMessage = mBufferIn.readLine();
if (mServerMessage != null && mMessageListener != null) {
// call the method messageReceived from MyActivity class
mMessageListener.messageReceived(mServerMessage);
}
}
MyLog.e("RESPONSE FROM SERVER", "S: Received Message: '"
+ mServerMessage + "'");
} catch (Exception e) {
MyLog.e("TCP", "S: Error", e);
} finally {
// the socket must be closed. It is not possible to reconnect to
// this socket
// after it is closed, which means a new socket instance has to
// be created.
socket.close();
}
} catch (Exception e) {
MyLog.e("TCP", "C: Error", e);
}
}
// Declare the interface. The method messageReceived(String message) will
// must be implemented in the MyActivity
// class at on asynckTask doInBackground
public interface OnMessageReceived {
public void messageReceived(String message);
}
}
public class Constants {
public static final String CLOSED_CONNECTION = "kazy_closed_connection";
public static final String LOGIN_NAME = "kazy_login_name";
}
@Override
protected void onPause() {
super.onPause();
if(connect != null) {
connect.cancel(true);
}
if(mTcpClient != null) {
MyLog.d(TAG, "stopClient");
mTcpClient.stopClient();
mTcpClient = null;
}
}
public class ConnectTask extends AsyncTask<String,String,TCPClient> {
@Override
protected TCPClient doInBackground(String... message) {
MyLog.d(TAG, "doInBackground");
//we create a TCPClient object and
mTcpClient = new TCPClient(new TCPClient.OnMessageReceived() {
@Override
//here the messageReceived method is implemented
public void messageReceived(String message) {
//this method calls the onProgressUpdate
publishProgress(message);
}
});
mTcpClient.run();
return null;
}
@Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
MyLog.d(TAG, "onProgressUpdate");
View view = adapter.getChildView(0, 0, false, null, null);
TextView text = (TextView) view.findViewById(R.id.betChildOdd);
child2.get(0).get(0).put("OLD", text.getText().toString());
child2.get(0).get(0).put(CONVERTED_ODDS, values[0].toString());
child2.get(0).get(0).put("CHANGE", "TRUE");
adapter.notifyDataSetChanged();
}
}
我没有仔细阅读您的所有代码,但我想到的第一件事是:您是基于多线程服务器架构构建应用程序的吗?对于我在代码中看到的内容,我注意到您没有将socket.accept()之后的执行委托给另一个线程,这就是您不能同时回答多个客户机的原因。
请记住,您需要注意对相同数据结构的并发访问可能产生的竞争条件。
这是TCP服务器应该遵循的模式:http://tutorials.jenkov.com/java-multithreaded-servers/multithreaded-server.html
在Netty中创建客户端连接时,我有一个问题。 这里,为什么我们没有一个bind方法,将通道绑定到发起客户端连接的端口(在客户端)?我们唯一需要提供的就是给出服务器地址和端口如下: 这是在客户端还是服务器端创建了一个新的通道?此通道绑定在客户端的哪个端口? 我们在执行服务器端引导时进行绑定,如下所示 我很困惑,不明白客户端从哪个端口向服务器发送数据,使用的是什么通道?
执行kafka客户端的生产者/消费者连接池有意义吗? kafka是否在内部维护已初始化并准备好使用的连接对象列表? 我们希望最小化连接创建的时间,这样在发送/接收消息时就不会有额外的开销。 目前,我们正在使用apache共享池库来保持连接。 任何帮助都将不胜感激。
我正在尝试从另一台机器创建与基于java的套接字服务器的多个客户端连接。服务器和客户端都使用Netty 4进行NIO。在服务器端,我使用了boss和Worker group,它能够在单个linux盒上接收和服务器100000并发连接(在设置内核参数和ulimited之后)。 但是,我最终在客户端为每个连接创建了一个新线程,这导致了JVM线程限制异常。 有人能告诉我,我如何使用Netty从客户端创建
我想知道以下问题的答案: 1)如果Ignite服务器重新启动,我需要重新启动客户端(web应用程序)。是否有任何方法可以在服务器重新启动时重新连接到服务器。我知道当服务器重新启动时,它分配了一个不同的ID,因此当前现有的连接变得过时。是否有方法克服这个问题,如果是的话,哪一个版本的Ignite支持这个功能。目前我使用1.7版本 3)如果我有一个大对象要缓存,我发现序列化和反序列化在Ignite中需
问题内容: 我正在设计一个将Redis用作数据库的Web服务,并且我想了解使用Redis与StackService客户端连接的最佳实践。 关键是我一直在阅读有关Redis的文章,发现与服务器交互的最佳方法是使用单个并发连接。 问题是,尽管每当Web客户端向Web服务发出请求时,我都会使用 PooledRedisClientManager ,但我又获得了一个到Redis服务器的连接客户端(打开的连接
按照这里的讨论,我使用以下步骤使外部客户端(基于 kafkajs)连接到 OpenShift 上的 Strimzi。这些步骤从这里开始。 被编辑为如下所示。 要提取证书并在客户端中使用它,我运行了以下命令: 请注意,我必须在我的macOS上使用,而不是,如留档所示。 这是从他们的 页面和他们的文档改编的客户端。 当我从具有的文件夹运行时,我收到一条连接拒绝消息。 我错过了什么?