Java 关于Socket

Java Socket主要有普通Socket和NioSocket

普通Socket又分为 ServerSocket和Socket两种,ServerSocket用于服务端,通过accept方法监听请求,然后返回给Socket。
客户端直接用Socket发起请求并传输数据。

Clinet

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

public class Client{
    public static void main(String[] args) {
        String msg = "Client Data";
        try {
            Socket socket = new Socket("127.0.0.1",10000);

            PrintWriter pw = new PrintWriter(socket.getOutputStream());

            BufferedReader is = new BufferedReader(new InputStreamReader(socket.getInputStream()));

            pw.println(msg);
            pw.flush();
            String line = is.readLine();
            System.out.println("received from Server: " + line);

            pw.close();
            is.close();
            socket.close();

        } catch (Exception e) {
            // TODO: handle exception
        }
    }
}

Server

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class Server{
    public static void main(String args[]){
        try {
            ServerSocket server = new ServerSocket(10000);
            Socket socket  = server.accept();

            BufferedReader is = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String line = is.readLine();
            System.out.println("receive:"+line);

            PrintWriter pw = new PrintWriter(socket.getOutputStream());
            pw.println("received data:"+line);
            pw.flush();

            pw.close();
            is.close();
            socket.close();
            server.close();

        } catch (Exception e) {
            // TODO: handle exception
        }
    }
}

java.nio包是Java在1.4之后增加的,用来提高I/O操作的效率。在nio包中主要包括以下几个类或接口:

  • Buffer:缓冲区,用来临时存放输入或输出数据。

  • Charset:用来把Unicode字符编码和其它字符编码互转。

  • Channel:数据传输通道,用来把Buffer中的数据写入到数据源,或者把数据源中的数据读入到Buffer。

  • Selector:用来支持异步I/O操作,也叫非阻塞I/O操作。

nio包中主要通过下面两个方面来提高I/O操作效率:

  • 通过Buffer和Channel来提高I/O操作的速度。

  • 通过Selector来支持非阻塞I/O操作。

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.SocketAddress;
import java.net.SocketOption;
import java.nio.ByteBuffer;
import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.Set;
import java.util.logging.Handler;


public class NIOSocket {
    public static void main(String[] args) throws Exception {
        //创建SeverSocketChannel,监听8080
        ServerSocketChannel ssc =  ServerSocketChannel.open();
        ssc.socket().bind(new InetSocketAddress(8080));

        //设置非阻塞
        ssc.configureBlocking(false);

        Selector selector = Selector.open();
        ssc.register(selector, SelectionKey.OP_ACCEPT);

        Handler handler = new Handler(1024);

        while(true){
            if(selector.select(3000) == 0){
                System.out.println("等待连接超时。。");
                continue;
            }
            System.out.println("处理请求。。");

            Iterator<SelectionKey> keyIter = selector.selectedKeys().iterator();

            while(keyIter.hasNext()){
                SelectionKey key = keyIter.next();
                try {
                    if(key.isAcceptable()){
                        handler.handleAccept(key);
                    }

                    if(key.isReadable()){
                        handler.handleRead(key);
                    }
                } catch (Exception e) {
                    // TODO: handle exception
                }
                keyIter.remove();
            }
        }


    }
    private static class Handler{
        private int bufferSize = 1024;
        private String localCharset = "utf-8";
        public Handler(){}
        public Handler(int bufferSize){
            this(bufferSize,null);
        }
        public Handler(String LocalCharset){
            this(-1,LocalCharset);
        }

        public Handler(int bufferSize,String localCharset){
            if(bufferSize > 0)
                this.bufferSize = bufferSize;
            if(localCharset != null)
                this.localCharset = localCharset;
        }
        public void handleAccept(SelectionKey key)throws IOException{
            SocketChannel sc = ((ServerSocketChannel)key.channel()).accept();
            sc.configureBlocking(false);
            sc.register(key.selector(), SelectionKey.OP_READ, ByteBuffer.allocate(bufferSize));
        }

        public void handleRead(SelectionKey key)throws IOException{
            SocketChannel sc = (SocketChannel)key.channel();
            ByteBuffer buffer = (ByteBuffer)key.attachment();
            buffer.clear();

            if(sc.read(buffer) == -1){
                sc.close();
            }else{
                buffer.flip();
                String receivedString = Charset.forName(localCharset).newDecoder()
                        .decode(buffer).toString();
                System.out.println("received form client: " + receivedString);

                String sendString = "received data: " + receivedString;
                buffer = ByteBuffer.wrap(sendString.getBytes(localCharset));
                sc.write(buffer);
                sc.close();
            }
        }
    }

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值