Я реализую простой tcp-чат между сервером и клиентом. Я использую многопоточность, так как сервер и клиент могут одновременно отправлять и получать данные (полный дуплекс). Программа работает, но если на сервере есть консоль, как для ввода отправляющего сообщения, так и для отображения получающего сообщения (в том же случае для клиента), я не могу редактировать свое введенное сообщение, которое должно быть отправлено на сервер или клиент, когда сообщение получено из другая сторона. Для например:java network programming TCP chat full duplex
запуска (консольного сервера):
ввода сообщ отправить клиента:
вы:
клиент: привет сервер
клиент: сервер bye.
В этом примере я набрал сообщение для отправки клиенту, в то время как клиент уже сказал hi server bye server. Перед получением от клиента, я вижу, что я набрал, но после получения, я не вижу сообщение или не редактирую его.
Я могу использовать консоль только потому, что им не очень хорошо с графическим интерфейсом, и мне нужна одна и та же консоль для отправки и получения данных.
Коды программы показаны ниже.
import java.net.*;
import java.io.*;
import java.util.Scanner;
public class ThreadServerSend implements Runnable {
String d;
Socket s1 = null;
Scanner sc = new Scanner(System.in);
public ThreadServerSend(Socket s)
{
s1=s;
}
public void run()
{
System.out.println("input msg to send client: ");
while (true){
try{
PrintStream p = new PrintStream(s1.getOutputStream());
System.out.println("you: ");
d=sc.nextLine();
p.println(d);
if (d.charAt(d.length()-1)=='.'){
s1.close();
break;}
}
catch(IOException e){}
}
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;
public class ThreadServerReceive implements Runnable {
String m;
Socket s2 = null;
Scanner sc = new Scanner(System.in);
public ThreadServerReceive(Socket s)
{
s2=s;
}
public void run()
{
while (true){
try{
BufferedReader b = new BufferedReader(new InputStreamReader(s2.getInputStream()));
m = b.readLine();
System.out.println("client: "+m);
if (m.charAt(m.length()-1)=='.'){
s2.close();
break;}}
catch(IOException e){}
}
}
}
import java.io.*;
import java.net.*;
import java.util.*;
public class Server {
public static void main(String[] args) throws UnknownHostException, IOException{
// TODO Auto-generated method stub
ServerSocket s = new ServerSocket(444);
Socket s1 = s.accept();
new Thread(new ThreadServerSend(s1)).start();
ServerSocket s4 = new ServerSocket(443);
Socket s2=s4.accept();
new Thread(new ThreadServerReceive(s2)).start();
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;
public class ThreadClientSend implements Runnable {
String d;
Socket s1 = null;
Scanner sc = new Scanner(System.in);
public ThreadClientSend(Socket s)
{
s1=s;
}
public void run()
{
System.out.println("Input msg to send server: ");
while (true){
try{
PrintStream p = new PrintStream(s1.getOutputStream());
System.out.println("you: ");
String d = new Scanner(System.in).nextLine();
p.println(d);
if (d.charAt(d.length()-1)=='.'){
s1.close();
break;}
}
catch(IOException e){}
}
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;
public class ThreadClientReceive implements Runnable {
String m;
Socket s1 = null;
Scanner sc = new Scanner(System.in);
public ThreadClientReceive (Socket s)
{
s1=s;
}
public void run()
{
while (true){
try{
BufferedReader b = new BufferedReader(new InputStreamReader(s1.getInputStream()));
m= b.readLine();
System.out.println("Server: "+m);
if (m.charAt(m.length()-1)=='.')
{
s1.close();
break;
}
}
catch(IOException e){}
}
}
}
import java.io.*;
import java.net.*;
import java.util.*;
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException{
// TODO Auto-generated method stub
Socket s1= new Socket("localhost",444);
Socket s2 = new Socket("localhost",443);
new Thread(new ThreadClientReceive(s1)).start();
new Thread(new ThreadClientSend(s2)).start();
}
}
консоль, вероятно, не лучший интерфейс для такой программы, так как есть на самом деле не каким-либо образом отделить текст ввода и вывода. Я думаю, вы найдете его намного лучше с простым графическим интерфейсом. Вы упоминаете, что вы плохо разбираетесь в графическом интерфейсе, но это кажется хорошей возможностью учиться! – ewanc
Да, я думаю, что я пойду с интерфейсом GUI. – ali
Это не должно быть сложно, всего пару текстовых областей и кнопка. Для простого графического интерфейса Swing большинство проблем, с которыми вы столкнетесь, вероятно, с менеджерами компоновки, они довольно ужасны в использовании. Но с небольшим количеством беспорядков вы получите его работу, и он продемонстрирует всю вашу работу намного лучше, чем консоль. Удачи! – ewanc