2016-03-04 4 views
0

Я реализую простой 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(); 




} 

} 
+0

консоль, вероятно, не лучший интерфейс для такой программы, так как есть на самом деле не каким-либо образом отделить текст ввода и вывода. Я думаю, вы найдете его намного лучше с простым графическим интерфейсом. Вы упоминаете, что вы плохо разбираетесь в графическом интерфейсе, но это кажется хорошей возможностью учиться! – ewanc

+0

Да, я думаю, что я пойду с интерфейсом GUI. – ali

+0

Это не должно быть сложно, всего пару текстовых областей и кнопка. Для простого графического интерфейса Swing большинство проблем, с которыми вы столкнетесь, вероятно, с менеджерами компоновки, они довольно ужасны в использовании. Но с небольшим количеством беспорядков вы получите его работу, и он продемонстрирует всю вашу работу намного лучше, чем консоль. Удачи! – ewanc

ответ

2

Немного поздно, но я действительно придумал рабочую версию этого чата для моего класса программирования. Я думал, что мог бы написать его здесь. Я использовал TCP (полный дуплекс) с поддержкой многопоточности, и я получил его для работы в консоли. Небольшая проблема заключается в том, что вы не можете видеть свое имя (потому что консоль имеет только одну активную строку), но в остальном это работает очень хорошо.

сервер (клиент более или менее то же самое, очевидно, Sockets нормальные розетки, не ServerSockets):

import java.net.*; 
import javax.swing.*; 
import java.awt.*; 
import java.util.*; 
import java.io.*; 
import java.awt.event.*; 
import java.awt.geom.*; 
import java.awt.image.*; 


@SuppressWarnings("serial") 
public class serverProgII extends Thread 
{ 

private static ObjectOutputStream oos; 
private static ObjectInputStream ois; 
private static Socket connection; 
private static ServerSocket server; 
private static String ip, clientIP, textin, exitword ="exit"; 
private static networkmessage nmessage; 
private static boolean connected = false; 
private static boolean done = false; 
private static String myName = ""; 
private static int counter = 0; 

public static boolean started = false; 
public String type; 

public static void main(String[] args) 
{ 
    try { 
     BufferedReader brin = new BufferedReader(new InputStreamReader(System.in)); 
     System.out.print("Enter your name:> "); //send prompt to DOS window 
     myName = brin.readLine();  //read in user input 
     setupConnection(); 
     setupStreams(); 
     started = true; 
    } catch (Exception e) { 
     System.out.println("Problem setting up streams and connection!"); 
    } 

    serverProgII sender = new serverProgII("sender"); 
    serverProgII receiver = new serverProgII("receiver"); 
    sender.start(); 
    receiver.start(); 
} 

public serverProgII(String t) 
{ 
    super(); 
    type = t; 
} 

public void run() { 
    while(started) { 
     switch(type) { 
      case "sender": 
       sender(); 
       break; 
      case "receiver": 
       receiver(); 
       break; 
     } 
     try { 
      Thread.sleep(500); //milliseconds 
     } catch(Exception e){} 
    } 
} 

/* runServer() 
    This is where all the actual work gets done. 
*/ 

public void sender() 
{ 
    try { 

     BufferedReader inn = new BufferedReader(new InputStreamReader(System.in)); 
     textin = inn.readLine(); 

     sendData(textin); 

     if (textin.equals(exitword)) // if "exit" is typed in shutdown the server. 
     { 
      started = false; 
      serverShutdown(); 
     } 

    } 
    catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

public void receiver() { 
    try { 
     getData(); 
    } catch(Exception e) { 
     System.out.println("Error getting data"); 
    } 
} 


//setup connection 
public static void setupConnection() throws IOException 
{ 
    System.out.println("SERVER MODE ACTIVATED"); 
    server = new ServerSocket (8000);      //create the socket at port 8000 
    System.out.println("Waiting For Connection..."); 
    connection = server.accept();       //wait for a connection 
    System.out.println("Received connection: "+connection.getInetAddress()); 
    clientIP=""+connection.getInetAddress();    //print out the client IP address 

}//setupconnection() 

//Setup streams connection 
public static void setupStreams() throws IOException 
{ 
    //Open up Streams 
    System.out.println("Streams Setup"); 
    oos=new ObjectOutputStream(connection.getOutputStream()); //construct object output stream 
    ois=new ObjectInputStream(connection.getInputStream()); 
    oos.flush(); 

}//setupStreams() 


//method to write/send network data 
public void sendData(String toSend) throws IOException 
{ 
    try 
    { 
     nmessage = new networkmessage(myName, toSend); 
     oos.writeObject(nmessage); 
    }//try 

    catch (IOException ioException) 
    { 
     System.out.println("IO exception in sendData"); 
    } 

}//sendData() 

//method to read in network data 
public void getData() throws IOException 
{ 
    try 
    { 
     networkmessage messageIn =(networkmessage)(ois.readObject()); 
     System.out.println(messageIn.ipnum +" << "+messageIn.text); 

    }//try 

    catch (Exception exp1) 
    { 
     System.out.println("IO exception in sendData"); 
    } 
}//getData() 


public void serverShutdown() 
{ 
    System.out.println("exiting initiated"); 

    try 
    { 
     done = true; 
     textin = "Chat is terminated. Have a nice day."; 
     oos.close(); 
     server.close(); 
     connection.close(); 
    } 

    catch (Exception One) 
    { 
     System.out.println("bad termination"); 
    } 
} 


} // class serverProg