简体   繁体   English

Java网络编程TCP聊天全双工

[英]java network programming TCP chat full duplex

I'm implementing a simple tcp chat between a server and a client. 我正在服务器和客户端之间实现一个简单的tcp聊天。 I'm using multi-threading so as the server and the client can send and receive data at the same time (full duplex). 我正在使用多线程,以便服务器和客户端可以同时发送和接收数据(全双工)。 The program works but if the server has a console for both typing the sending message and also displaying receiving message (same case for client), I cannot edit my typed message that should be sent to server or client when a message has been received from the other side. 该程序可以运行,但是如果服务器同时具有用于键入发送消息和显示接收消息的控制台(对于客户端,则是相同的情况),那么当从服务器接收到消息时,我不能编辑应发送给服务器或客户端的键入消息。另一边。 For eg: 例如:

run(server console): 运行(服务器控制台):

input msg to send client: 输入消息以发送客户端:

you: 您:

client: hi server 客户端:嗨服务器

client: bye server. 客户:再见服务器。

For this example, i've typed a message to send to client while the client has already said hi server bye server. 对于此示例,我已经键入了要发送给客户端的消息,而客户端已经说了“嗨,再见”。 Before receiving from client, i see what i've typed but after receiving, I can't see the msg nor edit it. 在从客户端收到消息之前,我会看到输入的内容,但是在收到消息后,看不到消息或对其进行编辑。

I can only use console because im not good with GUI and i want the same console for both sending and receiving data. 我只能使用控制台,因为不能很好地使用GUI,并且我希望使用同一控制台发送和接收数据。

The codes for the program are shown below. 该程序的代码如下所示。

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();




}

}

A bit late, but I actually came up with a working version of this chat client for my programming class. 有点晚了,但是我实际上为我的编程班想出了这个聊天客户端的工作版本。 I thought I might as well post it here. 我想我最好把它张贴在这里。 I used TCP (full duplex) with multithreading, and I got it to work in console. 我将TCP(全双工)与多线程一起使用,并且可以在控制台中使用它。 The small problem is that you can't see your own name (because console has only one active line), but otherwise it works pretty well. 一个小问题是您看不到自己的名字(因为控制台只有一个活动行),但否则效果很好。

Server (client is more or less the same, obviously the Sockets are normal sockets, not ServerSockets ): 服务器(客户端大致相同,显然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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM