【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();
}
}
}
}
上一篇: 在没有看到照片之前一直是这样认为的