[英]java network programming TCP chat full duplex
我正在服務器和客戶端之間實現一個簡單的tcp聊天。 我正在使用多線程,以便服務器和客戶端可以同時發送和接收數據(全雙工)。 該程序可以運行,但是如果服務器同時具有用於鍵入發送消息和顯示接收消息的控制台(對於客戶端,則是相同的情況),那么當從服務器接收到消息時,我不能編輯應發送給服務器或客戶端的鍵入消息。另一邊。 例如:
運行(服務器控制台):
輸入消息以發送客戶端:
您:
客戶端:嗨服務器
客戶:再見服務器。
對於此示例,我已經鍵入了要發送給客戶端的消息,而客戶端已經說了“嗨,再見”。 在從客戶端收到消息之前,我會看到輸入的內容,但是在收到消息后,看不到消息或對其進行編輯。
我只能使用控制台,因為不能很好地使用GUI,並且我希望使用同一控制台發送和接收數據。
該程序的代碼如下所示。
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();
}
}
有點晚了,但是我實際上為我的編程班想出了這個聊天客戶端的工作版本。 我想我最好把它張貼在這里。 我將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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.