首页 > 代码库 > java-socket编程

java-socket编程

先前有篇博文专门写了socket的基本概念,这里用java来实现简单的server-client的socket数据传输。

server端

/**
 * socket服务端
 * 
 * @author peter_wang
 * @create-time 2014-8-30 下午3:25:27
 */
public class Server {

    public static void main(String args[])
        throws IOException {
        int port = 8888;
        ServerSocket server = new ServerSocket(port);
        while (true) {
            // 开始接受socket请求
            Socket socket = server.accept();
            // 建立新线程处理新进的socket请求
            new Thread(new Task(socket)).start();
        }
    }

    /**
     * 处理Socket请求的异步任务
     */
    static class Task
        implements Runnable {

        private Socket mSocket;

        public Task(Socket socket) {
            this.mSocket = socket;
        }

        public void run() {
            try {
                handleSocket();
            }
            catch (Exception e) {
                e.printStackTrace();
            }
        }

        /**
         * 跟客户端Socket进行通信
         * 
         * @throws Exception
         */
        private void handleSocket()
            throws Exception {
            BufferedReader br = new BufferedReader(new InputStreamReader(mSocket.getInputStream(), "UTF-8"));
            StringBuilder sb = new StringBuilder();
            String temp;
            int index;
            while ((temp = br.readLine()) != null) {
                // 遇到eof时结束接收
                if ((index = temp.indexOf("eof")) != -1) {
                    System.out.println(temp);
                    sb.append(temp.substring(0, index));
                    break;
                }
                sb.append(temp);
            }
            System.out.println("data from client: " + sb);
            // 写操作
            Writer writer = new OutputStreamWriter(mSocket.getOutputStream());
            writer.write("Hello Client.");
            writer.write("eof\n");
            writer.flush();
            writer.close();
            br.close();
            mSocket.close();
        }
    }

}

client端

/**
 * socket客户端
 * 
 * @author peter_wang
 * @create-time 2014-8-30 下午4:13:11
 */
public class Client {

    public static void main(String args[])
        throws Exception {
        String host = "127.0.0.1"; // 本地地址
        int port = 8888;
        // 与服务端建立连接
        Socket client = new Socket(host, port);
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();
        System.out.println("输入的内容为:" + str);
        // 建立连接后就可以往服务端写数据了
        Writer writer = new OutputStreamWriter(client.getOutputStream(), "UTF-8");
        writer.write(str);
        writer.write("eof\n");
        writer.flush();
        // 写完以后进行读操作
        BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream()));
        StringBuffer sb = new StringBuffer();
        String temp;
        int index;
        while ((temp = br.readLine()) != null) {
            if ((index = temp.indexOf("eof")) != -1) {
                sb.append(temp.substring(0, index));
                break;
            }
            sb.append(temp);
        }
        System.out.println("from server: " + sb);
        writer.close();
        br.close();
        client.close();
    }

}

1.用了eof做完读写结束标识。

2.BufferedReader提高了IO效率,用异步提前准备好数据存储到内存,读取直接从内存读,如果数据来源于磁盘IO或网络IO,速度将快很多,磁盘读取和内存读取的速度对比参见这篇文章。

3.server和client之间数据传输需要统一编码,防止乱码。

4.源码分析,server端的new ServerSocket(port)实现了new socket、bind、listener功能

public void bind(SocketAddress endpoint, int backlog) throws IOException {
	if (isClosed())
	    throw new SocketException("Socket is closed");
	if (!oldImpl && isBound())
	    throw new SocketException("Already bound");
	if (endpoint == null)
	    endpoint = new InetSocketAddress(0);
	if (!(endpoint instanceof InetSocketAddress))
	    throw new IllegalArgumentException("Unsupported address type");
	InetSocketAddress epoint = (InetSocketAddress) endpoint;
	if (epoint.isUnresolved())
	    throw new SocketException("Unresolved address");
	if (backlog < 1)
	  backlog = 50;
	try {
	    SecurityManager security = System.getSecurityManager();
	    if (security != null)
		security.checkListen(epoint.getPort());
	    getImpl().bind(epoint.getAddress(), epoint.getPort());
	    getImpl().listen(backlog);
	    bound = true;
	} catch(SecurityException e) {
	    bound = false;
	    throw e;
	} catch(IOException e) {
	    bound = false;
	    throw e;
	}
    }
client端的new Socket(host, port)实现了new socket和connect功能

private Socket(SocketAddress address, SocketAddress localAddr,
		   boolean stream) throws IOException {
	setImpl();

	// backward compatibility
	if (address == null)
	    throw new NullPointerException();

	try {
	    createImpl(stream);
	    if (localAddr != null)
		bind(localAddr);
	    if (address != null)
		connect(address);
	} catch (IOException e) {
	    close();
	    throw e;
	}
    }



java-socket编程