powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Проблемы с построением клиент-серверного приложения (чат)
3 сообщений из 3, страница 1 из 1
Проблемы с построением клиент-серверного приложения (чат)
    #37826593
Exordin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте. Я начинающий программист. Хожу на курсы по Java где дали задание написать чат, который работате по сети.
Я начал реализовывать механизмы чата и первым делом хотел реализовать проверку на наличие пользователей на сервере, и сразу столкнулся с проблемой.
Для реализации чата я создал форму, класс клиента и класс сервера, и отдельный класс с методом main в котором создаётся обьект класса клиента и в EventQueue.invokeLater() запускается форма, принимая на вход обьект созданного класса клиента.
По моему задуму логика должна была работать так:
1. Пои нажатии кнопки Connect - форма должна была считать имя пользователя, которое введено в соответствующее поле, и передать его обьекту класса клиента.
2. Далее в классе формы должен был вызваться метод класса клиента, который создаёт подключение к серверу через сокет, и в этом методе он должен передать серверу имя пользователя, а тот в свою очередь должен был отвечать, по факту, есть пользователь или нет, и взависимости от этого форма должна была поменять свои аттрибуты (затенить кнопку Connect, сделать поле имени пользователя нечитаемым, и кнопку send активной, и кнопку disconnect активной), если пользователя нет, и выйти по return; если пользователь уже имелся. Но при нажатии кнопки Connect ничего не происходит и форма виснет, и даже не перерисовывается, а когда её принудительно Terminate то в консоль со стороны сервера выбрасывается следующее:
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
at sun.nio.cs.StreamDecoder.read(Unknown Source)
at java.io.InputStreamReader.read(Unknown Source)
at java.io.BufferedReader.fill(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at tasks.one.ChatServer.connectionsEstablisher(ChatServer.java:42)
at tasks.one.ChatServer.main(ChatServer.java:63)

Эксепшн в линии 42 это попытка сервера прочитать из сокета:
Код: java
1.
String connectedClientUsername = usernameGetter.readLine();



Я хотел бы понять, что здесь не так. Из-за чего виснет форма, и сервер не читает строку, хотя я записываю её в сокет и вызываю flush(); Я прочитал немало информации по многопоточности в интернете, но пока всё равно не могу понять в чём дело. А может проблема тут и не в многопоточности.
Если у вас найдётся время - помогите пожалуйста. Я понимаю, что это не совсем касается чата, которого ожидают на курсах, но мне кажется, что я застрял в каком-то фундаментальном принципе, который должен знать, по этому не могу от него отстать. Он меня мучает. PS: На курсах - те немногие, которые сделали чат - нагуглокодили, и не огут обьяснить как он работает, у преподавателя в этом тоже нет времени разбираться.
Спасибо.
Коды классов:
Класс Сервера:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
public class ChatServer {
//************************************************************************************
	final int pORT = 4004;
	ServerSocket serverSocket;
	Thread serverThread;
	private volatile Map<String, Socket> clients = new HashMap<String, Socket>();
	BufferedReader usernameGetter;
	BufferedWriter userPresenceNotification;
//************************************************************************************
	public ChatServer() {
		try {
			serverSocket = new ServerSocket(pORT);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
//************************************************************************************
	void connectionsEstablisher(){
		serverThread = Thread.currentThread();
			while(true){
				try {
					Socket connection = serverSocket.accept();
					if(connection != null){
						usernameGetter = new BufferedReader(new InputStreamReader(connection.getInputStream()));
						userPresenceNotification = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream()));
						String connectedClientUsername = usernameGetter.readLine();
						if(checkExistingUser(connectedClientUsername)){
							clients.put(connectedClientUsername, connection);
							Thread connectedSocketThread = new Thread(new SocketHandler(connection));
							connectedSocketThread.setDaemon(true);
							connectedSocketThread.start();
							userPresenceNotification.write("Success"); //dummy command
						} else {
							userPresenceNotification.write("Exists");
						}
					}
					userPresenceNotification.flush();
					usernameGetter.close();
					userPresenceNotification.close();
				} catch (IOException e) {
					e.printStackTrace();
				} 
			}
	}
//************************************************************************************
	public static void main(String[] args) {
		new ChatServer().connectionsEstablisher();

	}
//************************************************************************************
	private class SocketHandler implements Runnable{
		Socket existingSocket;
		BufferedReader existingSocketReader;
		BufferedWriter existingSocketWriter;
		
		SocketHandler(Socket connected){
			existingSocket = connected;
			try {
				existingSocketReader = new BufferedReader(new InputStreamReader(existingSocket.getInputStream(), "UTF-8"));
				existingSocketWriter = new BufferedWriter(new OutputStreamWriter(existingSocket.getOutputStream(), "UTF-8"));
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		@Override
		public void run() {
			while(!existingSocket.isClosed()){
				/*/TEST
				try {
					Thread.sleep(2000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				Set<Entry<String, Socket>> users = clients.entrySet();
				Iterator<Entry<String, Socket>> it = users.iterator();
				while(it.hasNext()){
					Entry<String, Socket> e = it.next();
					System.out.println(e.getKey() + " " + e.getValue());
				}
				//TEST*/
			}
		}
	}
//************************************************************************************
	private boolean checkExistingUser(String username){
		boolean result =true;
			Set<String> alreadyConnectedUsers = clients.keySet();
			for(String s : alreadyConnectedUsers){
				if(s.contentEquals(username)){
					result = false;
					break;
				}
			}
		return result;
	}
//************************************************************************************	
}


Класс клиента:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
public class ChatClient implements Runnable{
//************************************************************************************
	String username;
	Socket toServerConnection;
	final int pORT = 4004; //<- Port
	final String hOST = "127.0.0.1"; // <-Host
	BufferedReader socketReader;
	BufferedWriter socketWriter;
//************************************************************************************
	public void passUsername(String user){
		username = user;
		//System.out.println(username);
	}
//************************************************************************************
	public boolean connectToServer(){
		boolean isConnected = true;
		try {
			toServerConnection = new Socket(hOST, pORT );
			socketReader = new BufferedReader(new InputStreamReader(toServerConnection.getInputStream()));
			socketWriter = new BufferedWriter(new OutputStreamWriter(toServerConnection.getOutputStream()));
			socketWriter.write(username);
			socketWriter.flush();
			if((socketReader.readLine()).contentEquals("Exists")){ // Если заккоментировать этот фрагмент
				isConnected = false;                           // программа работает согласно
			}                                                  // булевому значению установленному изначально.

		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return isConnected;
	}
//************************************************************************************	
@Override
public void run() {
	
	
}

}


Класс формы(конкретно кнопки Connect. Всё остальное, пока, сплошное форматирование):
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
bConnect.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				if((userName = tfUsername.getText()).contentEquals("")){
					JOptionPane.showMessageDialog(ChatWindow.this, "Введи имя пользователя!", "Варнинг!", JOptionPane.WARNING_MESSAGE);
					return;
				}
				clientProgram.passUsername(userName);
				if(clientProgram.connectToServer()){
					tfUsername.setEditable(false);
					bDisconnect.setEnabled(true);
					bSend.setEnabled(true);
					bConnect.setEnabled(false);
					repaint();
				} else {
					JOptionPane.showMessageDialog(ChatWindow.this, "Такой юзер уже чатится!", "Эррор!", JOptionPane.ERROR_MESSAGE);
					return;
				}
			}
		});


tfUserName - ссылка на поле ввода имени пользователя;
clientProgram - ссылка на обьект класса клиента полученого через конструктор.
...
Рейтинг: 0 / 0
Проблемы с построением клиент-серверного приложения (чат)
    #37826604
rfq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Exordin,

сервер выполняет операцию readLine() и ждет символ конца строки. Клиент послал строку, но без символа конца. Надо еще выполнить socketWriter.newLine().
...
Рейтинг: 0 / 0
Проблемы с построением клиент-серверного приложения (чат)
    #37826620
Exordin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rfq,

Таки да!! :) Спасибо вам!
Я вычитал где-то, что, чтобы это всё работало - нужно оформлять строку .write(переменная_типа_String + "\n"), чтоб произошёл перевод строки, но это не срабатывало. А то, что вы посоветовали - помогло :)
Ещё раз спасибо :)
...
Рейтинг: 0 / 0
3 сообщений из 3, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / Проблемы с построением клиент-серверного приложения (чат)
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]