java - SocketChannel 客户端-服务器
问题描述
客户端连接到服务器,然后进入以下循环。它从控制台获取一行输入,将其发送到服务器。如果输入行是单个“x”字符,则客户端退出。
服务器
首先,它将自己的套接字地址打印到屏幕上。当它接收到一个连接时,它将对等端的套接字地址打印到屏幕上(这样你就可以检查谁连接到了服务器),然后进入下面的循环。它从客户端接收一行消息,将收到的消息打印到屏幕上。
非阻塞模式
客户端应使用缓冲区和非阻塞套接字通道。
阻塞模式
服务器应该使用缓冲区和阻塞套接字通道。
问题
我遇到的问题是服务器端的缓冲区没有刷新,而是用新输入打印旧输入。例子:
收到消息:你好
收到消息:helloworld
收到消息:helloworldthis
收到消息:helloworldthisis
收到的消息:helloworldthisis Edwin
它应该打印:你好
世界
这
是
埃德温。
这是服务器源代码:
public class EchoServer_1
{
// private static CharBuffer buffer = CharBuffer.allocate(1024);
private static ByteBuffer buffer = ByteBuffer.allocate(1024);
private static StringBuffer reqString = new StringBuffer();
public static void main(String[] args) throws IOException
{
ServerSocketChannel serverSocketChannel = null;
int serverPort = 10007;
try{
serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.socket().bind(new InetSocketAddress (serverPort));
//Blocking mode
serverSocketChannel.configureBlocking(true);
System.out.println("Port number: " + serverPort);
System.out.println("Waiting for connection ..");
SocketChannel sc = serverSocketChannel.accept();
System.out.println ("Incoming connection from: "
+ sc.socket().getRemoteSocketAddress( ));
// Read message from client
while (true)
{
buffer.clear();
sc.read(buffer);
buffer.flip();
while(buffer.hasRemaining()) {
char c = (char) buffer.get();
if (c == '\r' || c == '\n') break;
reqString.append(c);
}
log("Message received: " + reqString);
}
}catch (IOException ex)
{
if (serverSocketChannel != null)
serverSocketChannel.close();
System.err.println("Client has disconneted");
}
}
private static void log(String str) {
System.out.println(str);
}
}
这是客户端源代码:
public class EchoClient_1
{
private static Scanner stdIn = new Scanner(System.in);
// private static CharBuffer buffer = CharBuffer.allocate(1024);
private static ByteBuffer buffer = ByteBuffer.allocate(256);
public static void main(String[] args) throws IOException
{
String hostname = new String ("127.0.0.1");
int port = 10007;
try{
InetSocketAddress address = new InetSocketAddress(hostname, port);
SocketChannel sC = SocketChannel.open(address);
sC.configureBlocking(false);
log("Local address: " + hostname + " connecting to Server on port " + port
+ "...");
String userInput;
System.out.println("Enter lines of characters: " );
while ((userInput = stdIn.nextLine()) != null)
{
//Checks if user wants to exit
if (userInput.equalsIgnoreCase("x"))
{
buffer.put (userInput.getBytes());
buffer.flip();
sC.write(buffer);
buffer.clear();
System.out.println("Closing ..");
sC.close();
break;
}
buffer.put (userInput.getBytes());
buffer.flip();
sC.write(buffer);
buffer.clear();
}
sC.close();
}catch (IOException ex)
{
}
}
private static void log(String str) {
System.out.println(str);
}
}
解决方案
你永远不会清算reqString
。您应该在登录后执行此操作。
推荐阅读
- bash - 使用 Shell 脚本在新文件中打印带有一些文本的日期
- powershell - SharePoint Online 更改外观主题不起作用
- php - 如何使用正则表达式按字符拆分字母数字字符串?
- docker - 允许 Docker 容器仅与主机通信
- javascript - 如何使用 JS 在 Mac 上模拟 Command + shift + esc?
- javascript - React TypeError:无法读取未定义的属性“文本”
- azure-devops - 在 azure-devops 中的发布管道期间创建标签
- google-cloud-platform - 将 GCP 项目迁移到另一个电子邮件/帐户
- algorithm - 给定一个数学链接的二维数组 (NxM),可以创建 log(N)log(M) 搜索算法吗
- javascript - HTML 表单验证 - 检查是否至少选择了一个下拉菜单