方式一
存在缺点
输入流与输出流在同一个线程内,应该独立处理,彼此独立
读的时候不能写,必须等写完才读
打印结果
111
服务器--》111
222
服务器--》222
333
服务器--》333
44
服务器--》44
服务器端
package com.anqi.tcp2;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(9998);
Socket socket = server.accept();
DataInputStream dis = new DataInputStream(socket.getInputStream());
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
//先读取后输出
while(true){
String str = dis.readUTF();
dos.writeUTF("服务器--》"+str);
dos.flush();
}
}
}
客户端
package com.anqi.tcp2;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
public class Client {
public static void main(String[] args) throws IOException, IOException {
Socket client = new Socket("localhost",9998);
//控制台输入流
BufferedReader console = new BufferedReader(
new InputStreamReader(System.in));
DataOutputStream dos = new DataOutputStream(client.getOutputStream());
while(true){
String info = console.readLine();
//输出流
dos.writeUTF(info);
dos.flush();
//输入流
DataInputStream dis = new DataInputStream(client.getInputStream());
String str = dis.readUTF();
System.out.println(str);
}
}
}
方式二
打印结果
运行服务器->运行一个客户端 输入a->运行一个客户端 输入 b->
两个客户端均显示
a
b
服务器端
package com.anqi.tcp3;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public class Server {
private List<MyChannel>all = new ArrayList<>();
public static void main(String[] args) throws IOException {
new Server().start();
}
public void start() throws IOException{
ServerSocket server = new ServerSocket(9998);
while(true){
Socket client = server.accept();
MyChannel channel = new MyChannel(client);
all.add(channel);//统一管理
new Thread(channel).start();//一条道路
}
}
/**
* 一个客户端一条道路
* 输入流
* 输入流
* 接收数据
* 发送数据
* @author Angel
*
*/
private class MyChannel implements Runnable{
DataInputStream dis;
DataOutputStream dos;
private boolean isRunning = true;
public MyChannel(Socket client){
try {
dis = new DataInputStream(client.getInputStream());
dos = new DataOutputStream(client.getOutputStream());
} catch (IOException e) {
isRunning = false;
CloseUtil.closeAll(dis,dos);
}
}
/**
* 读取数据
* @return
*/
private String receive(){
String msg = null;
try {
msg = dis.readUTF();
} catch (IOException e) {
isRunning = false;
CloseUtil.closeAll(dis);
all.remove(this);//移除自身
}
return msg;
}
/**
* 发送数据
*/
private void send(String msg){
if(msg == null || msg.equals(""))
return;
try {
dos.writeUTF(msg);
dos.flush();
} catch (IOException e) {
isRunning = false;
CloseUtil.closeAll(dos);
all.remove(this);//移除自身
}
}
/**
* 发送给其他客户端
*/
private void sendOthers(){
String msg = receive();
//遍历容器
for (MyChannel others : all) {
if(others == this)
continue;
//发送给其他客户端
others.send(msg);
}
}
public void run() {
while(isRunning){
sendOthers();
}
}
}
}
客户端
package com.anqi.tcp3;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
public class Client {
public static void main(String[] args) throws IOException, IOException {
Socket client = new Socket("localhost",9998);
//控制台输入流
new Thread(new Send(client)).start();//一条路径
new Thread(new Receive(client)).start();//一条路径
}
}
Send.java
package com.anqi.tcp3;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
/**
* 发送数据
* @author Angel
*
*/
public class Send implements Runnable{
//控制台输入流
private BufferedReader console;
//管道输出流
private DataOutputStream dos;
//控制线程
private boolean isRunning = true;
public Send(){
console = new BufferedReader(
new InputStreamReader(System.in));
}
public Send(Socket client){
this();
try
{
dos = new DataOutputStream(client.getOutputStream());
} catch (IOException e) {
isRunning = false;
CloseUtil.closeAll(dos,console);
}
}
/**
* 从控制台接收数据
* @return
*/
private String getMsgFromConsole(){
try {
return console.readLine();
} catch (IOException e) {
}
return "";
}
/**
* 1.从控制台接收数据
* 2.发送数据
*/
public void send(){
String msg = getMsgFromConsole();
if(msg != null && !msg.equals("")){
try {
dos.writeUTF(msg);
dos.flush();
} catch (IOException e) {
isRunning = false;
CloseUtil.closeAll(dos,console);
}
}
}
public void run() {
//线程体
while(isRunning){
send();
}
}
}
Receive.java
package com.anqi.tcp3;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;
/**
* 接收数据
* @author Angel
*
*/
public class Receive implements Runnable{
//输入流
private DataInputStream dis;
//线程控制
private boolean isRunning = true;
Receive(){
}
Receive(Socket client){
try {
dis = new DataInputStream(client.getInputStream());
} catch (IOException e) {
isRunning = false;
CloseUtil.closeAll(dis);
}
}
/**
* 接收数据
* @return
*/
public String receive(){
String msg = "";
try {
msg = dis.readUTF();
} catch (IOException e) {
isRunning = false;
CloseUtil.closeAll(dis);
}
return msg;
}
public void run() {
//线程体
while(isRunning){
System.out.println(receive());
}
}
}
关闭的工具类
package com.anqi.tcp3;
import java.io.Closeable;
import java.io.IOException;
/**
* 关闭流的方法
* @author Angel
*
*/
public class CloseUtil {
public static void closeAll(Closeable ... io){
for (Closeable closeable : io) {
if (closeable != null)
try
{
closeable.close();
} catch (IOException e) {}
}
}
}