Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 357|回复: 0

[默认分类] 一个Android Socket的例子

[复制链接]
  • TA的每日心情
    开心
    2021-12-13 21:45
  • 签到天数: 15 天

    [LV.4]偶尔看看III

    发表于 2018-7-12 16:13:15 | 显示全部楼层 |阅读模式
    1.开篇简介
      Socket本质上就是java封装了传输层上的TCP协议(注:UDP用的是DatagramSocket类)。要实现Socket的传输,需要构建客户端和服务器端。另外,传输的数据可以是字符串和字节。字符串传输主要用于简单的应用,比较复杂的应用(比如Java和C++进行通信),往往需要构建自己的应用层规则(类似于应用层协议),并用字节来传输。
    2.基于字符串传输的Socket案例
      1)服务器端代码(基于控制台的应用程序,模拟)

    1. import java.io.BufferedReader;
    2. import java.io.BufferedWriter;
    3. import java.io.IOException;
    4. import java.io.InputStreamReader;
    5. import java.io.OutputStreamWriter;
    6. import java.io.PrintWriter;
    7. import java.net.ServerSocket;
    8. import java.net.Socket;
    9. import java.util.ArrayList;
    10. import java.util.List;
    11. import java.util.concurrent.ExecutorService;
    12. import java.util.concurrent.Executors;
    13. public class Main {
    14.     private static final int PORT = 9999;
    15.     private List<Socket> mList = new ArrayList<Socket>();
    16.     private ServerSocket server = null;
    17.     private ExecutorService mExecutorService = null; //thread pool
    18.    
    19.     public static void main(String[] args) {
    20.         new Main();
    21.     }
    22.     public Main() {
    23.         try {
    24.             server = new ServerSocket(PORT);
    25.             mExecutorService = Executors.newCachedThreadPool();  //create a thread pool
    26.             System.out.println("服务器已启动...");
    27.             Socket client = null;
    28.             while(true) {
    29.                 client = server.accept();
    30.                 //把客户端放入客户端集合中
    31.                 mList.add(client);
    32.                 mExecutorService.execute(new Service(client)); //start a new thread to handle the connection
    33.             }
    34.         }catch (Exception e) {
    35.             e.printStackTrace();
    36.         }
    37.     }
    38.     class Service implements Runnable {
    39.             private Socket socket;
    40.             private BufferedReader in = null;
    41.             private String msg = "";
    42.             
    43.             public Service(Socket socket) {
    44.                 this.socket = socket;
    45.                 try {
    46.                     in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    47.                     //客户端只要一连到服务器,便向客户端发送下面的信息。
    48.                     msg = "服务器地址:" +this.socket.getInetAddress() + "come toal:"
    49.                         +mList.size()+"(服务器发送)";
    50.                     this.sendmsg();
    51.                 } catch (IOException e) {
    52.                     e.printStackTrace();
    53.                 }
    54.                
    55.             }
    56.             @Override
    57.             public void run() {
    58.                 try {
    59.                     while(true) {
    60.                         if((msg = in.readLine())!= null) {
    61.                             //当客户端发送的信息为:exit时,关闭连接
    62.                             if(msg.equals("exit")) {
    63.                                 System.out.println("ssssssss");
    64.                                 mList.remove(socket);
    65.                                 in.close();
    66.                                 msg = "user:" + socket.getInetAddress()
    67.                                     + "exit total:" + mList.size();
    68.                                 socket.close();
    69.                                 this.sendmsg();
    70.                                 break;
    71.                                 //接收客户端发过来的信息msg,然后发送给客户端。
    72.                             } else {
    73.                                 msg = socket.getInetAddress() + ":" + msg+"(服务器发送)";
    74.                                 this.sendmsg();
    75.                             }
    76.                         }
    77.                     }
    78.                 } catch (Exception e) {
    79.                     e.printStackTrace();
    80.                 }
    81.             }
    82.           /**
    83.            * 循环遍历客户端集合,给每个客户端都发送信息。
    84.            */
    85.            public void sendmsg() {
    86.                System.out.println(msg);
    87.                int num =mList.size();
    88.                for (int index = 0; index < num; index ++) {
    89.                    Socket mSocket = mList.get(index);
    90.                    PrintWriter pout = null;
    91.                    try {
    92.                        pout = new PrintWriter(new BufferedWriter(
    93.                                new OutputStreamWriter(mSocket.getOutputStream())),true);
    94.                        pout.println(msg);
    95.                    }catch (IOException e) {
    96.                        e.printStackTrace();
    97.                    }
    98.                }
    99.            }
    100.         }   
    101. }
    复制代码

      2)Android客户端代码

    1. package com.amaker.socket;
    2. import java.io.BufferedReader;
    3. import java.io.BufferedWriter;
    4. import java.io.IOException;
    5. import java.io.InputStreamReader;
    6. import java.io.OutputStreamWriter;
    7. import java.io.PrintWriter;
    8. import java.net.Socket;
    9. import android.app.Activity;
    10. import android.app.AlertDialog;
    11. import android.content.DialogInterface;
    12. import android.os.Bundle;
    13. import android.os.Handler;
    14. import android.os.Message;
    15. import android.view.View;
    16. import android.widget.Button;
    17. import android.widget.EditText;
    18. import android.widget.TextView;
    19. public class SocketDemo extends Activity implements Runnable {
    20.     private TextView tv_msg = null;
    21.     private EditText ed_msg = null;
    22.     private Button btn_send = null;
    23.     // private Button btn_login = null;
    24.     private static final String HOST = "10.0.2.2";
    25.     private static final int PORT = 9999;
    26.     private Socket socket = null;
    27.     private BufferedReader in = null;
    28.     private PrintWriter out = null;
    29.     private String content = "";
    30.     //接收线程发送过来信息,并用TextView显示
    31.     public Handler mHandler = new Handler() {
    32.         public void handleMessage(Message msg) {
    33.             super.handleMessage(msg);
    34.             tv_msg.setText(content);
    35.         }
    36.     };
    37.     @Override
    38.     public void onCreate(Bundle savedInstanceState) {
    39.         super.onCreate(savedInstanceState);
    40.         setContentView(R.layout.main);
    41.         tv_msg = (TextView) findViewById(R.id.TextView);
    42.         ed_msg = (EditText) findViewById(R.id.EditText01);
    43.         btn_send = (Button) findViewById(R.id.Button02);
    44.         try {
    45.             socket = new Socket(HOST, PORT);
    46.             in = new BufferedReader(new InputStreamReader(socket
    47.                     .getInputStream()));
    48.             out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
    49.                     socket.getOutputStream())), true);
    50.         } catch (IOException ex) {
    51.             ex.printStackTrace();
    52.             ShowDialog("login exception" + ex.getMessage());
    53.         }
    54.         btn_send.setOnClickListener(new Button.OnClickListener() {
    55.             @Override
    56.             public void onClick(View v) {
    57.                 // TODO Auto-generated method stub
    58.                 String msg = ed_msg.getText().toString();
    59.                 if (socket.isConnected()) {
    60.                     if (!socket.isOutputShutdown()) {
    61.                         out.println(msg);
    62.                     }
    63.                 }
    64.             }
    65.         });
    66.         //启动线程,接收服务器发送过来的数据
    67.         new Thread(SocketDemo.this).start();
    68.     }
    69.     /**
    70.      * 如果连接出现异常,弹出AlertDialog!
    71.      */
    72.     public void ShowDialog(String msg) {
    73.         new AlertDialog.Builder(this).setTitle("notification").setMessage(msg)
    74.                 .setPositiveButton("ok", new DialogInterface.OnClickListener() {
    75.                     @Override
    76.                     public void onClick(DialogInterface dialog, int which) {
    77.                     }
    78.                 }).show();
    79.     }
    80.     /**
    81.      * 读取服务器发来的信息,并通过Handler发给UI线程
    82.      */
    83.     public void run() {
    84.         try {
    85.             while (true) {
    86.                 if (!socket.isClosed()) {
    87.                     if (socket.isConnected()) {
    88.                         if (!socket.isInputShutdown()) {
    89.                             if ((content = in.readLine()) != null) {
    90.                                 content += "\n";
    91.                                 mHandler.sendMessage(mHandler.obtainMessage());
    92.                             } else {
    93.                             }
    94.                         }
    95.                     }
    96.                 }
    97.             }
    98.         } catch (Exception e) {
    99.             e.printStackTrace();
    100.         }
    101.     }
    102. }
    复制代码

      解析:除了isClose方法,Socket类还有一个isConnected方法来判断Socket对象是否连接成功。  看到这个名字,也许读者会产生误解。  其实isConnected方法所判断的并不是Socket对象的当前连接状态,  而是Socket对象是否曾经连接成功过,如果成功连接过,即使现在isClose返回true, isConnected仍然返回true。因此,要判断当前的Socket对象是否处于连接状态, 必须同时使用isClose和isConnected方法, 即只有当isClose返回false,isConnected返回true的时候Socket对象才处于连接状态。 虽然在大多数的时候可以直接使用Socket类或输入输出流的close方法关闭网络连接,但有时我们只希望关闭OutputStream或InputStream,而在关闭输入输出流的同时,并不关闭网络连接。这就需要用到Socket类的另外两个方法:shutdownInput和shutdownOutput,这两个方法只关闭相应的输入、输出流,而它们并没有同时关闭网络连接的功能。和isClosed、isConnected方法一样,Socket类也提供了两个方法来判断Socket对象的输入、输出流是否被关闭,这两个方法是isInputShutdown()和isOutputShutdown()。 shutdownInput和shutdownOutput并不影响Socket对象的状态。

    2.基于字节的传输
      基于字节传输的时候,只需要把相应的字符串和整数等类型转换为对应的网络字节进行传输即可。具体关于如何把其转换为网络字节,请参《网路搜集:java整型数与网络字节序的 byte[] 数组转换关系》。

    PS: 欢迎关注公众号"Devin说",会不定期更新Java相关技术知识。
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-4-25 17:29 , Processed in 0.449655 second(s), 46 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表