安卓中基于socket的网络通讯

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
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值