欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【Socket网络通信】利用TCP/IP协议实现服务端与客户端的双向聊天

程序员文章站 2022-06-06 14:35:27
...

服务器:

 

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

/**
 *  @author $KangMiao$
 *  服务端
 * 与TCPTalkClient02.java一起用
 * 利用TCP/IP协议实现服务端与客户端的双向聊天
 * 问题:①当服务端输入quit时 ,我输入的信息客户端接收不到,但可以看到客户端发来的信息。
 * (已解决) 在两个线程中分别关闭相应的流
 */

public class TCPTalkServer02 {
	public void talk() {
		try {
			ServerSocket ss = new ServerSocket(8888);  
			System.out.println("聊天服务器开启···");
			Socket s = null;
			while ((s = ss.accept()) != null) {
				System.out.println(s.getInetAddress()+"朋友来访中-----");
				ThreadTalk tt = new ThreadTalk(s);
				tt.start();
			}

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

	public static void main(String[] args) {
		TCPTalkServer02 talk = new TCPTalkServer02();
		talk.talk();
	}
}

class ThreadTalk extends Thread {
	private Socket s;
	private BufferedReader br;
	private BufferedReader brConsole;
	private PrintStream ps;
	private InetAddress ip;

	public ThreadTalk(Socket s) {
		this.s = s;
	}

	public void run() {
		try {
			br = new BufferedReader(new InputStreamReader(s
					.getInputStream()));// 从客户端读取数据
			brConsole = new BufferedReader(
					new InputStreamReader(System.in)); // 从服务端读取数据
			ps = new PrintStream(s.getOutputStream()); // 向客户端输入数据
			//获得客户端ip地址
			ip = s.getInetAddress();
			ps.println("服务端传话:欢迎访问聊天服务器!");
			TalkThread tat = new TalkThread(brConsole, ps);
			tat.start(); // 这里用到多线程 实现双方互相对话
			String temp = "";
			while ((temp = br.readLine()) != null) {
				if (temp.equalsIgnoreCase("quit")) {
					System.out.println("与第" + ip+ "断开连接!");
					ps.println("断开连接,欢迎下次访问!");
					break;
				}
				System.out.println( ip+"说:" + temp);
			}
		} catch (IOException e) {
			if("Connection reset".equals(e.getMessage())){
				System.out.println("客户端异常退出!");
			}
		}finally {
			try {
				br.close();
				System.out.println(ip+"已断开链接!");
				s.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

class TalkThread extends Thread {
	private BufferedReader brConsole;
	private PrintStream ps;

	public TalkThread( BufferedReader brConsole,PrintStream ps) {
		super();
		this.brConsole = brConsole;
		this.ps = ps;
	}

	public void run() {
		String temp = "";
		try {
			while ((temp = brConsole.readLine())!= null) {
				ps.println(temp);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				brConsole.close();
				ps.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

 

 

 

客户端:

/**
 * @author $KangMiao$
 * 客户端
 * 与TCPTalkServer02.java一起用
 * 建立TCP双向通信客户端
 * 问题:①当客服端输入quit时 断开连接 但弹出异常,如下:
 * (已解决) 
 * java.net.SocketException: socket closed
	at java.net.SocketInputStream.socketRead0(Native Method)
	at java.net.SocketInputStream.read(Unknown Source)
	at sun.nio.cs.StreamDecoder$CharsetSD.readBytes(Unknown Source)
	at sun.nio.cs.StreamDecoder$CharsetSD.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 com.wepull.task.zuoye11.TalkThred3.run(TcpClient.java:76)
 */

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class TCPTalkClient02 {
	private Socket s;
	private BufferedReader consBr; //控制台输入流
	private PrintStream ps;    //网络输出流
	private BufferedReader br;
	 
	public void conn(){
		 try {
			s = new Socket("localhost",8888);
			br = new BufferedReader(new InputStreamReader(s.getInputStream()));
			ps = new PrintStream(s.getOutputStream()); //写给服务端
			consBr = new BufferedReader(new InputStreamReader
					(System.in));       //从控制台读取数据
			TalkThred4 tt = new TalkThred4(consBr,ps);
			tt.start();
			String temp1 = "";
			while ((temp1 = br.readLine())!= null) {
				if (temp1.equalsIgnoreCase("quit")) {
					System.out.println("服务端与你断开连接!");
					break;
				}
				System.out.println("服务端传话:" +temp1);
			}
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			try {
				br.close();
				ps.close();
				s.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	public static void main(String[] args) {
		TCPTalkClient02 tc = new TCPTalkClient02();
		System.out.println("客户端连接中·········");
		tc.conn();
	}
}

class TalkThred4 extends Thread {
	private BufferedReader consBr;
	private PrintStream ps;

	public TalkThred4( BufferedReader consBr,PrintStream ps) {
		super();
		this.consBr = consBr;
		this.ps = ps;
	}

	public void run() {
		String temp = null;
		try {
			while((temp = consBr.readLine())!=null){
				ps.println(temp);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				consBr.close();
				ps.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}