Я выполняю упражнение, требующее создания программы чата между сервером и клиентом с использованием Java Non-Blocking IO
. На данный момент программа работает просто: когда клиент отправляет сообщение на сервер, сервер (который уже отслеживает всех клиентов) отправляет сообщение обратно всем клиентам.
Это мои некоторые части моего кода на стороне сервера:
public static ByteBuffer str_to_bb(String msg) {
try {
return encoder.encode(CharBuffer.wrap(msg));
} catch(Exception e) {
e.printStackTrace();
}
return null;
}
private static void broadcastMessage(String nickname, String message) {
System.out.println(">clientSocketChannels size " + clientSocketChannels.size());
Iterator clientSocketChannelsIterator = clientSocketChannels.iterator();
while (clientSocketChannelsIterator.hasNext()) {
SocketChannel sc = (SocketChannel) clientSocketChannelsIterator.next();
try {
ByteBuffer bb = str_to_bb(message);
System.out.println("bufferRemaining: " + bb.remaining()); // returns 2048
int writeResult = sc.write(bb);
System.out.println("writeResult: " + writeResult); // returns 2048
} catch (IOException e) {
e.printStackTrace();
}
}
}
Ниже приведен мой клиентский код:
import javax.swing.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
/**
* Created by ThaiSon on 7/6/2015.
*/
public class ChatRoomClientGUI {
private JTextArea textAreaMessages;
private JTextField textFieldMessage;
private JButton buttonSendMsg;
private JPanel jPanel1;
private JLabel txtFieldInfo;
private static InetAddress inetAddress;
private static final int PORT = 1234;
private static Socket socket = null;
private static Scanner input = null;
private static PrintWriter output = null;
private static ChatRoomClientGUI singleton;
public ChatRoomClientGUI() {
singleton = this;
buttonSendMsg.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
if (e.getButton() == MouseEvent.BUTTON1) {
String message = textFieldMessage.getText();
output.println(message);
textFieldMessage.setText("");
}
}
});
}
public static void main(String[] args) {
JFrame promptFrame = new JFrame();
Object nickname = JOptionPane.showInputDialog(promptFrame, "Enter your nickname:");
promptFrame.dispose();
JFrame frame = new JFrame("ChatRoomClientGUI");
frame.setContentPane(new ChatRoomClientGUI().jPanel1);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
System.out.println("> Client with nickname " + nickname);
try {
inetAddress = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
e.printStackTrace();
}
accessServer(nickname.toString());
}
private static void accessServer(String nickname) {
try {
socket = new Socket(inetAddress, PORT);
input = new Scanner(socket.getInputStream());
output = new PrintWriter(socket.getOutputStream(), true);
output.println(nickname); // Register nickname with the server
//TODO update the txtFieldInfo content
// Create a new thread to listen to InputStream event
InputStreamEvent inputStreamEvent = new InputStreamEvent(socket);
inputStreamEvent.start();
} catch (IOException e) {
e.printStackTrace();
}
}
private static void handleInputStream(){
String response = input.nextLine();
System.out.println("TODO " + response);
singleton.textAreaMessages.append(response + "\n");
}
static class InputStreamEvent extends Thread{
Socket socket;
public InputStreamEvent(Socket socket){
this.socket = socket;
}
public void run(){
try {
InputStream inputStream = socket.getInputStream();
byte[] buffer = new byte[2048];
int read;
while (true){
if(inputStream.available() > 0){
handleInputStream();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Проблема, с которой я сталкиваюсь сейчас, заключается в том, что когда я использую клиент (который хорошо работает со старым multithreaded server
) для отправки сообщения на сервер, клиент возвращает только первое сообщение, которое он отправляет. Все последующие ответы от сервера пустые (сервер отправляет обратно, но только пустое сообщение).
Итак, мои попытки отладки включают:
- проверьте, доходят ли сообщения от клиента до сервера или нет. Они делают.
- запишите результаты
buffer.remaining()
иsocketChannel.write(buffer)
, как показано выше, все результаты журнала кажутся мне нормальными.
Надеюсь, вы, ребята, можете помочь мне с этим.
encoder
иclientSocketChannels
? - person WorldSEnder   schedule 06.07.2015encoder
находится здесь: изpublic static Charset charset = Charset.forName("UTF-8"); public static CharsetEncoder encoder = charset.newEncoder(); public static CharsetDecoder decoder = charset.newDecoder();
(я копирую его из этого вопроса: stackoverflow.com/questions/1252468/), а clientSocketChannels - это ArrayList всех SocketChannels (каждый SocketChannel относится к одному клиенту, который подключается к серверу ) - person sonlexqt   schedule 06.07.2015sc.write(bb); sc.flush();
- person Zymus   schedule 06.07.2015nextLine
, но сообщение, которое вы отправляете, не имеет разделителя строк в конце. Попробуйте сделатьCharBuffer.wrap(msg + "\r\n")
в своем методеstr_to_bb
. - person Zymus   schedule 07.07.2015