Java 通信netty服务器-Socket客户端
Java Communication netty server - Socket client
对于聊天服务器项目,我使用 netty 作为服务器,在我的处理程序中使用以下代码:
public class PacketHandler extends ChannelInboundHandlerAdapter{
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
ByteBuf in = (ByteBuf) msg;
try {
AbstractClientPacket packet = ClientPacketHandler.handle(in);
if(packet != null && packet.read()){
packet.run();
ctx.write(msg+"\r\n");
}
} finally {
ReferenceCountUtil.release(msg);
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}
因此,我的数据包得到了正确处理并且工作正常,但是随后,我 ctx.write(msg+"\r\n");
将消息发回我的客户端,就像回显服务器一样。
这是客户代码:
public class ChatClient {
static Socket socket;
static DataOutputStream out;
static BufferedReader in;
public static void main(String[] args){
try {
initSocket();
String test = "Salut 1";
TestPacket packet = new TestPacket(0x18,test.getBytes());
sendPacket(packet);
while(true){
try {
String message = in.readLine();
System.out.println(message);
} catch (IOException e) {
e.printStackTrace();
}
}
//TEST
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private static void initSocket(){
try {
socket = new Socket("localhost",58008);
out = new DataOutputStream(socket.getOutputStream());
in = new BufferedReader(new InputStreamReader((socket.getInputStream())));
} catch (IOException e) {
e.printStackTrace();
}
}
private static void sendPacket(TestPacket p) throws IOException{
out.write(p.getRawData());
out.flush();
}
}
数据包已正确发送,但我没有收到任何回复,当我停止我的服务器时,由于我的 while(true)
,客户端正在发送空垃圾邮件,但我没有收到我的消息,什么都没有显示,我真的不知道为什么。
我不能在客户端使用netty,因为这个只是为了测试目的,最终的客户端将用C#(Unity Engine)编写,所以我不能在这个中使用netty,我必须使用本机套接字处理来完成。
编辑:
根据 wireshark,来自客户端的数据包已发送但服务器没有回答,我没有看到包含 "Salut 1".
的来自服务器的数据包
你做到了:
ctx.write(msg+"\r\n");
msg
不是 String
,而是 ByteBuf
。如果要将 \r\n
附加到收到的消息,您应该执行以下操作:
in.writeByte('\r');
in.writeByte('\n');
ctx.write(in);
此外,由于您将收到的消息 (in
) 重新用作回复,因此不应释放它:
// Do NOT call this.
ReferenceCountUtil.release(in);
如果您真的打算调用 ctx.write(msg + "\r\n")
,请确保您的管道有 StringEncoder
。
对于聊天服务器项目,我使用 netty 作为服务器,在我的处理程序中使用以下代码:
public class PacketHandler extends ChannelInboundHandlerAdapter{
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
ByteBuf in = (ByteBuf) msg;
try {
AbstractClientPacket packet = ClientPacketHandler.handle(in);
if(packet != null && packet.read()){
packet.run();
ctx.write(msg+"\r\n");
}
} finally {
ReferenceCountUtil.release(msg);
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}
因此,我的数据包得到了正确处理并且工作正常,但是随后,我 ctx.write(msg+"\r\n");
将消息发回我的客户端,就像回显服务器一样。
这是客户代码:
public class ChatClient {
static Socket socket;
static DataOutputStream out;
static BufferedReader in;
public static void main(String[] args){
try {
initSocket();
String test = "Salut 1";
TestPacket packet = new TestPacket(0x18,test.getBytes());
sendPacket(packet);
while(true){
try {
String message = in.readLine();
System.out.println(message);
} catch (IOException e) {
e.printStackTrace();
}
}
//TEST
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private static void initSocket(){
try {
socket = new Socket("localhost",58008);
out = new DataOutputStream(socket.getOutputStream());
in = new BufferedReader(new InputStreamReader((socket.getInputStream())));
} catch (IOException e) {
e.printStackTrace();
}
}
private static void sendPacket(TestPacket p) throws IOException{
out.write(p.getRawData());
out.flush();
}
}
数据包已正确发送,但我没有收到任何回复,当我停止我的服务器时,由于我的 while(true)
,客户端正在发送空垃圾邮件,但我没有收到我的消息,什么都没有显示,我真的不知道为什么。
我不能在客户端使用netty,因为这个只是为了测试目的,最终的客户端将用C#(Unity Engine)编写,所以我不能在这个中使用netty,我必须使用本机套接字处理来完成。
编辑:
根据 wireshark,来自客户端的数据包已发送但服务器没有回答,我没有看到包含 "Salut 1".
的来自服务器的数据包你做到了:
ctx.write(msg+"\r\n");
msg
不是 String
,而是 ByteBuf
。如果要将 \r\n
附加到收到的消息,您应该执行以下操作:
in.writeByte('\r');
in.writeByte('\n');
ctx.write(in);
此外,由于您将收到的消息 (in
) 重新用作回复,因此不应释放它:
// Do NOT call this.
ReferenceCountUtil.release(in);
如果您真的打算调用 ctx.write(msg + "\r\n")
,请确保您的管道有 StringEncoder
。