1.BIO
客户端简单编写
public static void main(String[] args) {
try {
//1.创建socket对象
Socket socket=new Socket("127.0.0.1", 9999);
//2.从socket 获取字节输入流
OutputStream out=socket.getOutputStream();
//字节输入流换成打印流
PrintStream ps=new PrintStream(out,true);
Scanner san=new Scanner(System.in);
while (true){
System.out.print("请说:");
ps.println(san.nextLine()) ;
}
} catch (IOException e) {
e.printStackTrace();
}
}
服务端简单编写
public static void main(String[] args) {
try {
System.out.println("开始注册端口");
//注册端口
ServerSocket serversocket=new ServerSocket(9999);
//循环获取socket 监听
while(true){
Socket so=serversocket.accept();
new ServerThread(so).start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
定义一个ServerThread线程类
public class ServerThread extends Thread{
private Socket socket;
public ServerThread(Socket so) {
this.socket=so;
}
@Override
public void run() {
try {
InputStream input=socket.getInputStream();
BufferedReader read=new BufferedReader(new InputStreamReader(input));
String msg;
while( (msg=read.readLine())!=null ){
System.out.println(msg);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
2. NIO 代码开发,同样也是实现客户端和服务端交互
客户端:
public class Client {
//1.选择器
private Selector selector;
//2.客户端通道
private SocketChannel socketChannel;
//3.端口
private static int PORT = 9998;
//4.IP
private static String IP="127.0.0.1";
//5.实例化
public Client(){
try {
//6.开启选择器
selector=Selector.open();
//7.开启通道
socketChannel=SocketChannel.open(new InetSocketAddress(IP,PORT));
//8.设置非阻塞
socketChannel.configureBlocking(false);
//9.绑定端口IP
// socketChannel.bind(new InetSocketAddress(IP,PORT));
//10 监听读事件
socketChannel.register(selector, SelectionKey.OP_READ);
System.out.println("客户端准备好了");
} catch (IOException e) {
System.out.println("客户端连接失败");
e.printStackTrace();
}
}
public static void main(String[] args) {
Client client=new Client();
System.out.println("转发线程启动");
new Thread(() -> {
System.out.println("开始转发");
client.readInfo();
}).start();
Scanner sc=new Scanner(System.in);
while (sc.hasNext()){
String msg= sc.nextLine();
client.writrToServer(msg);
System.out.println("-------------");
}
}
private void writrToServer(String msg) {
try {
socketChannel.write(ByteBuffer.wrap(msg.getBytes()));
} catch (IOException e) {
e.printStackTrace();
}
}
private void readInfo() {
try {
while(selector.select()>0) {
Iterator<SelectionKey> it =selector.selectedKeys().iterator();
while(it.hasNext()){
//取数
SelectionKey sk=it.next();
if(sk.isReadable()){
SocketChannel sc= (SocketChannel) sk.channel();
ByteBuffer bf=ByteBuffer.allocate(1024);
sc.read(bf);
bf.flip();
System.out.println(new String(bf.array(),0,bf.remaining()));
System.out.println("----转发结束---------");
}
it.remove();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
服务端:
public class Server {
//1.
private ServerSocketChannel sschannel;
//2.
private Selector selector;
//3.定义端口
private final int PORT=9998;
//构造器
public Server(){
try {
//开启选择器,初始化选择器
selector=Selector.open();
//开启通道
sschannel=ServerSocketChannel.open();
//设置非阻塞
sschannel.configureBlocking(false);
//设置连接
sschannel.bind(new InetSocketAddress(PORT));
//注册连接事件
sschannel.register(selector, SelectionKey.OP_ACCEPT);
} catch (IOException e) {
e.printStackTrace();
}
}
public void connect() {
try {
System.out.println("服务端准备就绪");
//有连接的事件就一直循环等待
while (selector.select()>0){
//迭代所有事件
Iterator<SelectionKey> it=selector.selectedKeys().iterator();
while (it.hasNext()){
//获取当前事件
SelectionKey sk= it.next();
//判断事件状态
if(sk.isAcceptable()){
//11.获取当前接入客户端通道
SocketChannel sc= sschannel.accept();
//设置事件通道阻塞
sc.configureBlocking(false);
//13.本客户端注册读事件到选择器
sc.register(selector,SelectionKey.OP_READ);
}else if(sk.isReadable()){
clientGetData(sk);
}
it.remove();
}
}
}catch (Exception e){
}
}
private void clientGetData(SelectionKey sk) {
//获取当前事件通道
SocketChannel socketChannel= null;
//分配空间
ByteBuffer bf=ByteBuffer.allocate(1024);
try {
socketChannel= (SocketChannel) sk.channel();
int leg=socketChannel.read(bf);
if(leg>0){
bf.flip();
String msg=new String(bf.array(),0,bf.remaining());
System.out.println("客户端接收消息:"+msg);
sendMsgAllclient(msg,socketChannel);
}
} catch (IOException e) {
System.out.println("有人离线了");
try {
sk.cancel();
socketChannel.close();
} catch (IOException ioException) {
ioException.printStackTrace();
}
e.printStackTrace();
}
}
private void sendMsgAllclient(String msg, SocketChannel socketChannel) {
System.out.println("服务端开始转发这个消息,当前线程:"+Thread.currentThread().getName());
for(SelectionKey skey : selector.keys()){
Channel channel= skey.channel();
if(channel instanceof SocketChannel && channel!=socketChannel){
ByteBuffer buffer=ByteBuffer.wrap(msg.getBytes());
try {
((SocketChannel) channel).write(buffer);
} catch (IOException e) {
System.out.println("为啥没有收到");
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
Server server=new Server();
server.connect();
}
}
