安卓中基于socket的网络通讯

来源:互联网 发布:淘宝评论好的句子 编辑:程序博客网 时间:2024/05/21 08:40

Socket 又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求。ServerSocket用于服务器端,Socket建立网络连接时使用的

在连接成功时,应用程序两端都会产生一个 Socket实例,通过操作这个实例,就可以完成相关的通讯和会话。

对于一个网络连接来说,套接字是平等的,并没有差别。

不管是Socket还是ServerSocket他们的工作都是通过socket类及其子类完成的。

 

Socket链接建立步骤:  相当于”三次握手”

1)服务器端监听连接请求、

2)客户端发出连接请求、

3)创建和确认连接

 

Socket特点:

1Socket链接基于TCP通信协议,连接有保障;

2Socket适用于建立长时间的链接;

3Socket编程通常用于即时通讯;


网络编程三要素:IP、协议、端口。



如何建立与ServerSocket的链接以及如何使用ServerSocket

在浏览器中输入127.0.0.1:65530  相当于访问本机的端口为65530的应用程序。 

ServerSocket   Socket   accept()   socket.getOutputStream()

package com.example.tuhuadmin.socketapplication;import java.io.IOException;import java.net.ServerSocket;import java.net.Socket;/** * Created by Tuhuadmin on 2016/7/15. * 如何与ServerSocket建立连接以及SocketServer的使用 */public class TestMyServerSocket {    public static void main(String[] args) {        try {            //需要传入一个端口号            //创建ServerSocket时会有异常抛出            ServerSocket serverSocket = new ServerSocket(65530);            //创建完成后,要监听客户端的连接请求,所以要调用它的阻塞方法accept();accept是阻塞方法,他会阻塞当前线程的执行,肯定不能放在主线程里面。            Socket socket = serverSocket.accept();            //一旦accept()被执行,表示有客户端连接上,就会产生一个服务器端的socket与之进行通讯            System.out.print("有客户端连接到本机!");            //在浏览器中输入127.0.0.1:65530 回车就可以看到输出的信息        } catch (IOException e) {            e.printStackTrace();        }    }}

简单的聊天服务器代码:

package com.example.tuhuadmin.socketapplication;/** * Created by Tuhuadmin on 2016/7/15. * 使用socket建立聊天服务器 */public class TestMyServerSocket {    public static void main(String[] args) {        //开启服务器端网络连接监听的线程        new ServerListener().start();        //在dos命令面板中输入  telnet localhost 65531,服务器端就可以收到,病打印输出语句。        //实现聊天室的功能:将服务器端所有的通讯线程保存到一个集合当中,当有用户发来数据,则转发给所有用户,实现聊天室效果。    }}


监听客户端网络请求;

package com.example.tuhuadmin.socketapplication;import java.io.IOException;import java.net.ServerSocket;import java.net.Socket;/** * Created by Tuhuadmin on 2016/7/15. */public class ServerListener extends Thread {    @Override    public void run() {        try {            //需要传入一个端口号            //创建ServerSocket时会有异常抛出            ServerSocket serverSocket = new ServerSocket(65531);            //创建完成后,要监听客户端的连接请求,所以要调用它的阻塞方法accept();accept是阻塞方法,他会阻塞当前线程的执行,肯定不能放在主线程里面。            while (true) {                Socket socket = serverSocket.accept();                //需要将socket传递给新的线程与服务器端进行通讯, 创建用于socket通讯的线程。                ChatSocket chatSocket = new ChatSocket(socket);                chatSocket.start();                ChatManager.getChatManager().addChatSocket(chatSocket);                // 此时每一个ChatSocket都是独立的线程,他们不能相互传递数据。            }            //一旦accept()被执行,表示有客户端连接上,就会产生一个服务器端的socket与之进行通讯            //每一个客户端的连接,都会返回一个Socket对象,所以要创建一个while循环,循环监听客户端的连接        } catch (IOException e) {            e.printStackTrace();        }        //对于有阻塞的方法(耗时操作),要把它放置到独立的线程中    }}
用于聊天的socket处理 业务逻辑

package com.example.tuhuadmin.socketapplication;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.FileWriter;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.OutputStreamWriter;import java.io.UnsupportedEncodingException;import java.net.Socket;/** * Created by Tuhuadmin on 2016/7/15. * 创建用于和客户端通讯的socket */public class ChatSocket extends Thread {    //为此类创建一个构造方法,并传入需要通讯的socket    private Socket socket;    public ChatSocket(Socket socket) {        this.socket = socket;    }    @Override    public void run() {        //在当前的线程中,要对当前的socket输出功能进行包装        out("你已经连接到本服务器了");        try {            //获取socket的输出流,通过输出流才可以向外输出数据。//            OutputStream outputStream = socket.getOutputStream();//            BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));            //让当前的socket循环输出   指定编码集            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream(), "utf-8"));            String line;            //循环执行读取数据的工作            while ((line = bufferedReader.readLine()) != null) {                //说明当前读取到了数据                ChatManager.getChatManager().sendMessage(this, line);            }            //关闭当前流            bufferedReader.close();        } catch (IOException e) {            e.printStackTrace();        }    }    public void out(String str) {        try {            socket.getOutputStream().write((str+"\n").getBytes("UTF-8"));        } catch (UnsupportedEncodingException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}
管理所有的聊天Socket

package com.example.tuhuadmin.socketapplication;import java.util.Vector;/** * Created by Tuhuadmin on 2016/7/15. */public class ChatManager {    //我们需要新建一个类,将每一个ChatSocket管理起来,然后实现他们之间的通讯    //由于一个聊天服务器只能有一个ChatManager,所以此ChatManager应该是单利模式    //单例模式:构造函数私有,不让创建对象;对外提供一个获取对象的方法    private static final ChatManager chatManager = new ChatManager();    //创建一个集合去管理    Vector<ChatSocket> vector = new Vector<ChatSocket>();    private ChatManager() {    }    public static ChatManager getChatManager() {        return chatManager;    }    //提供一个方法,把所有的ChatSocket添加到ChatMananger里面    public void addChatSocket(ChatSocket chatSocket) {        vector.add(chatSocket);    }    //其中的一个ChatSocket可以通过调用此方法和其他的ChatSocket进行通讯    //把线程本身传递进来,传入当前需要发送的信息    public void sendMessage(ChatSocket chatSocket, String message) {        //既然要发送给集合中所有的通讯线程,就需要对集合进行遍历        for (int i = 0; i < vector.size(); i++) {            //在这里进行判断,因为当前发送信息的线程,就不需要接收信息了,            ChatSocket cs = vector.get(i);            if (!cs.equals(chatSocket)) {                cs.out(message);            }        }    }}                                                                                                                                                                                                         </span>

1 0
原创粉丝点击