간단한 채팅을하고 있는데, 서버와 클라이언트가 연결되어있는 것보다 훨씬 간단합니다. 클라이언트 측에서 소켓 등을 생성하는 것을 관리하는 ConnectionManager 클래스가 있습니다. 여기 핵심 방법이 있습니다 :java - 서버가 클라이언트로부터 메시지를받지 못합니다 (reader.readLine() == null?)
public class ConnectionManager {
private Socket socket;
private BufferedReader reader;
private PrintWriter writer;
public ConnectionManager(String URL, int port){
tryConnectToServer(URL, port);
}
public BufferedReader getReader() {
return reader;
}
public PrintWriter getWriter() {
return writer;
}
private void tryConnectToServer(String ip, int servSocket) {
try{
socket = new Socket(ip, servSocket);
writer = new PrintWriter(socket.getOutputStream());
reader = new BufferedReader(
new InputStreamReader(
socket.getInputStream()));
}
catch (IOException ex){
System.out.println("Unable to connect to specified server. Code pink");
ex.printStackTrace();
}
}
연결 관리자 개체는 ChatGUI의 일부입니다. ChatGUI의 필드 라이터와 리더 SendButtonListener로 수득 ChatGUI의 JTextField로 (msgInput)와 함께 라이터를 전달하기 위해 CM에서 설정된다
private void addSendButton() {
JButton sendButton = new JButton("Send");
sendButton.addActionListener(new SendButtonActionListener(writer, msgInput));
panel.add(sendButton);
panel.add(this.msgArea);
}
이어서, actionPerformed 메소드는 않는다 :
public class SendButtonActionListener implements ActionListener{
private PrintWriter writer;
private JTextField msgInput;
public SendButtonActionListener(PrintWriter pr, JTextField mi){
writer = pr;
msgInput = mi;
}
public void actionPerformed(ActionEvent event){
writer.println(msgInput.getText());
System.out.println("Sending: " + msgInput.getText());
flushMessageInputField();
}
private void flushMessageInputField(){
msgInput.setText("");
}
}
다른 한편 서버 쪽에서 나는 이것을 가지고있다 :
try{
this.servSocket = new ServerSocket(port);
System.out.println("Server socket established");
}
catch (IOException ex){
System.out.println("Unable to establish server socket. Code pink \n");
ex.printStackTrace();
}
그리고 위의 후이 온다 :
public void waitForClients(){
System.out.println("The gates has been opened...");
while (true){
try {
Socket client = servSocket.accept();
processClient(client);
}
catch (IOException ex){
ex.printStackTrace();
}
}
}
private void processClient(Socket client){
writers.add(getClientWriter(client));
startUpdateFrom(client);
System.out.println("New client connected: " + client.getPort());
}
private PrintWriter getClientWriter(Socket client){
try{
return new PrintWriter(client.getOutputStream());
}
catch (Exception ex){
ex.printStackTrace();
}
return null;
}
그리고 마지막으로, 새로운 스레드가 해당 클라이언트에서 새 메시지를 듣고 시작합니다입니다
private void startUpdateFrom(Socket client){
new Thread(
new WaitAndSendToAllFrom(client))
.start();
}
:
public class WaitAndSendToAllFrom implements Runnable{
BufferedReader reader;
public WaitAndSendToAllFrom(Socket clientSocket){
try{
reader = new BufferedReader(
new InputStreamReader(
clientSocket.getInputStream()));
}
catch (IOException ex){
ex.printStackTrace();
}
}
public void run(){
try{
String message;
System.out.println("Thread: waiting for messages to send...");
while (true){
message = reader.readLine();
while (message != null){
System.out.println("Server: Sending message: " + message);
sendToAll(message);
}
}
}
catch (IOException ex){
ex.printStackTrace();
}
}
private void sendToAll(String message){
List<PrintWriter> writers = ServerClientConnector.getWriters();
for (PrintWriter pr : writers){
pr.println(message + "\n");
pr.flush();
}
}
}
사이클은 "스레드 : 메시지를 보내기를 기다리는 중 ..."이되지만 더 이상 필요하지는 않습니다. reader.readLine()은 널 (sysout으로 확인)을 리턴합니다. 나는 그것을 디버깅하려했지만, 그렇게 많은 프로그래밍에 익숙하지 않았다. 특히 두 개의 서로 다른 코드를 서로 디버깅하는 것이었다. 나는 이것을 3 일 동안보고 있었고, 나는 심각하게 여기에서 붙어있다.
당신은뿐만 아니라 클라이언트에서 메시지를 전송하는 코드를 게시 할 수 있습니까? 그건 그렇고, while (message! = null)'while.loop 내에서 메시지가 바뀌지 않으므로, WaitAndSendToAllFrom-> run-> while에 무한 루프가 있습니다. 당신이 요청한 문제는 다음 일 수 있습니다). –
글을 쓰지 않고 글을 편집했지만 그게 전부라고 생각합니다 :). 다른 버그/오류를 미리 미리 - 나는 코드가 릴 비트와 리팩토링으로 변경되어야한다는 것을 알고 있지만, 지금은 그 소켓/독자/작가에 집중하고 있습니다. :) –