Socket的简单实现

本文对Socket作简单的整理:

Socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求。抽象出来,Socket实质上提供了进程通信的端点。进程通信之前,双方首先必须各自创建一个端点,否则是没有办法建立联系并相互通信的。

下面是Socket 的Java实现:

一:服务器端的实现

<span style="font-size:18px;">	public static int PORT = 8080;

	public static void main(String[] agrs) {
		ServerSocket s = null;
		Socket socket = null;
		BufferedReader br = null;
		PrintWriter pw = null;
		try {
			// 设定服务端的端口号
			s = new ServerSocket(PORT);
			System.out.println("ServerSocket Start:" + s);
			// 等待请求,此方法会一直阻塞,直到获得请求才往下走
			socket = s.accept();
			System.out.println("Connection accept socket:" + socket);
			// 用于接收客户端发来的请求
			br = new BufferedReader(new InputStreamReader(socket
					.getInputStream()));
			// 用于发送返回信息,可以不需要装饰这么多io流使用缓冲流时发送数据要注意调用.flush()方法
			pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
					socket.getOutputStream())), true);
			while (true) {
				String str = br.readLine();
				if (str.equals("END")) {
					break;
				}
				System.out.println("Client Socket Message:" + str);
				Thread.sleep(1000);
				pw.println("Message Received");
				pw.flush();
			}

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			System.out.println("Close.....");
			try {
				br.close();
				pw.close();
				socket.close();
				s.close();
			} catch (Exception e2) {

			}
		}
	}</span>

二:客户端的实现

<span style="font-size:18px;">    public static void main(String[] args) {  
        Socket socket = null;  
        BufferedReader br = null;  
        PrintWriter pw = null;  
        try {  
            //客户端socket指定服务器的地址和端口号  
            socket = new Socket("127.0.0.1",8080);  
            System.out.println("Socket=" + socket);  
            //同服务器原理一样  
            br = new BufferedReader(new InputStreamReader(  
                    socket.getInputStream()));  
            pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())));
            for (int i = 0; i < 10; i++) {  
                pw.println("client " + i);  
                pw.flush();  
                String str = br.readLine();  
                System.out.println(str);  
            }  
            pw.println("END");  
            pw.flush();  
        } catch (Exception e) {  
            e.printStackTrace();  
        } finally {  
            try {  
                System.out.println("close......");  
                br.close();  
                pw.close();  
                socket.close();  
            } catch (IOException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            }  
        }  
    } </span>

三:Android客户端的实现,我们一般写在事件回调中

<span style="font-size:18px;">        button.setOnClickListener(new OnClickListener() {  
            @Override  
            public void onClick(View v) {  
                Socket socket = null;  
                String message = editText.getText().toString()+ "\r\n" ;  
                try {  
                    //创建客户端socket,注意:不能用localhost或127.0.0.1,Android模拟器把自己作为localhost  
                    socket = new Socket("10.62.13.243",9192);  
                    PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);  
                    //发送数据  
                    out.println(message);  
                      
                    //接收数据  
                    BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));  
                    String msg = in.readLine();  
                    if (null != msg){  
                        editText.setText(msg);  
                        System.out.println(msg);  
                    }  
                    else{  
                        editText.setText("data error");  
                    }  
                    out.close();  
                    in.close();  
                } catch (UnknownHostException e) {  
                    e.printStackTrace();  
                } catch (IOException e) {  
                    e.printStackTrace();  
                }  
                finally{  
                    try {  
                        if (null != socket){  
                            socket.close();  
                        }  
                    } catch (IOException e) {  
                        e.printStackTrace();  
                    }  
                }  
            }  
        }); </span>


上面的代码还是比较简单的

四:socket的缺点:

传统socket:阻塞式通信
每建立一个Socket连接时,同时创建一个新线程对该Socket进行单独通信(采用阻塞的方式通信)。
这种方式具有很高的响应速度,并且控制起来也很简单,在连接数较少的时候非常有效,但是如果
对每一个连接都产生一个线程的无疑是对系统资源的一种浪费,如果连接数较多将会出现资源不足的情况。

五:针对Socket的缺点,Java提出了nio:非阻塞通讯模式

NIO 设计背后的基石:反应器模式,用于事件多路分离和分派的体系结构模式。
反应器模式的核心功能如下:
将事件多路分用  将事件分派到各自相应的事件处理程序

NIO 的非阻塞 I/O 机制是围绕 选择器和 通道构建的。 Channel 类表示服务器和客户机之间的
一种通信机制。Selector 类是 Channel 的多路复用器。 Selector 类将传入客户机请求多路分
用并将它们分派到各自的请求处理程序。
通道(Channel 类):表示服务器和客户机之间的一种通信机制。
选择器(Selector类):是 Channel 的多路复用器。Selector 类将传入的客户机请求多路分用并将它们
分派到各自的请求处理程序。

简单的来说:

NIO是一个基于事件的IO架构,最基本的思想就是:有事件我通知你,你再去做你的事情.
而且NIO的主线程只有一个,不像传统的模型,需要多个线程以应对客户端请求,也减轻了JVM的工作量。

针对NIO这种思想,目前已经有了比较成熟的框架:Apache MINA.


本文的例子下载



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值