我使用套接字进行培训,为此,我在本地主机上进行聊天服务。 我的问题是当发送查询到服务器,使用昵称服务器必须向我发送确认或错误(昵称可以使用或不使用)。 但只有当客户端向服务器发送第二个消息时,服务器才会给客户一个答案:确认和同时向第二个查询发送消息。 这不是我想要的,我已经尝试找到服务器是否接收到查询并且它已经收到了。
我的服务器代码,用于提供用户名:
static private void resolveUsername(Selector sel, SelectionKey key, String nick) throws IOException {
for (SelectionKey k : sel.keys()) {
if(k.isValid() && k.channel() instanceof SocketChannel)
if(((User)k.attachment()).getNick().equals(nick)) {
SocketChannel sct = (SocketChannel)key.channel();
sct.write(enc.encode(CharBuffer.wrap("ERROR")));
return;
}
}
if( ((User)key.attachment()).state() == State.INSIDE) {
for (SelectionKey k : sel.keys()){
if(k.isValid() && k.channel() instanceof SocketChannel){
if(!((User)k.attachment()).getNick().equals(((User)key.attachment()).getNick())){
SocketChannel sct = (SocketChannel)key.channel();
sct.write(enc.encode(CharBuffer.wrap("NEWNICK "+((User)key.attachment()).getNick() +" "+ nick))); }
}
}
}
((User)key.attachment()).setNick(nick);
SocketChannel sct = (SocketChannel)key.channel();
sct.write(enc.encode(CharBuffer.wrap("OK")));
}
我的服务器代码发送消息:
message = it.getNick() +":"+ message;
for (SelectionKey k : sel.keys()) {
if(k.isValid() && k.channel() instanceof SocketChannel) {
SocketChannel sct = (SocketChannel)k.channel();
sct.write(enc.encode(CharBuffer.wrap(message)));
}
}
我的客户端在一个单独的线程中读取代码:
public void run() {
while(open) {
String modifiedSentence ="";
try {
modifiedSentence = inFromServer.readLine();
} catch(IOException e) {
System.out.println("ERROR");}
System.out.println(modifiedSentence);
if(!modifiedSentence.equals(""))
chatArea.append(modifiedSentence+'\n');
}
}
我向服务器发送查询:
public void newMessage(String message) throws IOException {
outToServer.writeBytes(message+'\n');
}
更新: 我使用netcat测试从服务器接收消息,并且它正确接收,所以我认为客户端是错误的。但我认为我做得很好,如果你需要,我会把我的客户代码。
public class ChatClient {
JFrame frame = new JFrame("Chat Client");
private JTextField chatBox = new JTextField();
private JTextArea chatArea = new JTextArea();
private Thread t;
private Socket clientSocket;
private DataOutputStream outToServer;
private BufferedReader inFromServer;
public void printMessage(final String message) {
chatArea.append(message);
}
public ChatClient(String server, int port) throws IOException {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.add(chatBox);
frame.setLayout(new BorderLayout());
frame.add(panel, BorderLayout.SOUTH);
frame.add(new JScrollPane(chatArea), BorderLayout.CENTER);
frame.setSize(500, 300);
frame.setVisible(true);
chatArea.setEditable(false);
chatBox.setEditable(true);
chatBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
newMessage(chatBox.getText());
} catch (IOException ex) {
} finally {
chatBox.setText("");
}
}
});
clientSocket = new Socket(server, port);
outToServer = new DataOutputStream(clientSocket.getOutputStream());
inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
t =new Thread(new Reader(chatArea, clientSocket,inFromServer));
t.start();
}
public void newMessage(String message) throws IOException {
outToServer.writeBytes(message+'\n');
}
public void run() throws IOException {
while(!clientSocket.isClosed()){
}
Reader.open=false;
}
public static void main(String[] args) throws IOException {
ChatClient client = new ChatClient(args[0], Integer.parseInt(args[1]));
client.run();
}
}
class Reader implements Runnable {
private JTextArea chatArea;
private Socket clientSocket;
public static Boolean open = true;
private BufferedReader inFromServer;
public Reader(JTextArea chatArea,Socket clientSocket,BufferedReader inFromServer){
this.chatArea = chatArea;
this.clientSocket = clientSocket;
this.inFromServer = inFromServer;
}
public void run(){
while(open){
System.out.println("TTT\n");
String modifiedSentence ="";
try{
modifiedSentence = inFromServer.readLine();
}catch(IOException e){
System.out.println("ERROR");
}
chatArea.append(modifiedSentence+'\n');
}
}
}
感谢您的时间。
答案 0 :(得分:1)
我使用netcat测试从服务器接收消息,并且它正确接收,所以我认为客户端是错误的。但我认为我做得很好......
您可能无法正确执行的操作是在客户端中使用.readLine()
,读取一行文本,而在服务器中则不会终止所有邮件使用换行符('\ n')或回车符('\ r')。