Android Sockdet

来源:互联网 发布:logstash 性能优化 编辑:程序博客网 时间:2024/06/07 05:40

1.简介

    Socket本质上就是Java封装了传输层上的TCP协议(注:UDP用的是DatagramSocket类)。要实现Socket的传输,需要构建客户端和服务器端。另外,传输的数据可以是字符串和字节。字符串传输主要用于简单的应用,比较复杂的应用(比如Java和C++进行通信),往往需要构建自己的应用层规则(类似于应用层协议),并用字节来传输。

2.服务器端

    直接上代码
public class MyServerSocket {    private Vector<ChatSocket> vector=new Vector<ChatSocket>();//存放所有的客户端socket         public MyServerSocket()         {             try{                 ServerSocket serverSocket=new ServerSocket(23);//服务端开启对端口13345的监听                 while(true){                    Socket socket=serverSocket.accept();//服务器端提供与客户端相对应的socket//                  JOptionPane.showMessageDialog(null, "已经有客户端连入");                    ChatSocket cs=new ChatSocket(socket,vector);//对每一个客户端都提供一个ChatSocket类来进行信息的交互                    add(cs);                    cs.start();                          }                     } catch (IOException e){                         // TODO 自动生成的 catch 块                         e.printStackTrace();                     }             }         public void add(ChatSocket csSocket)//服务器端添加每一个客户端socket         {                 vector.add(csSocket);             }        public static void main(String[]args)        {                 new MyServerSocket();             }}
public class ChatSocket extends Thread {    Socket socket;        Vector<ChatSocket> vector;         public ChatSocket(Socket s,Vector<ChatSocket>vector)         {                 this.socket=s;                 this.vector = vector;             }         public void out(String out)//服务器发送消息给客户端         {                try             {                    BufferedWriter bfWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));                     bfWriter.write(out);                 System.out.println(out + "--00-");                    bfWriter.flush();//清空缓冲区,避免消息延迟显示                 } catch (UnsupportedEncodingException e)            {                    // TODO 自动生成的 catch 块                     e.printStackTrace();                } catch (IOException e)             {                    // TODO 自动生成的 catch 块                     e.printStackTrace();                 }             }         @Override         public void run()         {                try                {                        BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(socket.getInputStream()));                         String line = null;                         while((line=bufferedReader.readLine())!=null)//服务端接收客户端的消息                             {//                                sendMessage(this, line);//转发给其他客户端//                                 System.out.println(line + "---");                                 BufferedWriter bfWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));                                 bfWriter.write(line);                                 System.out.println(line + "--00-");                                 bfWriter.flush();//清空缓冲区,避免消息延迟显示                             }//                        bufferedReader.close();                     } catch (IOException e)                {                         // TODO 自动生成的 catch 块                        e.printStackTrace();                    }             }       public void sendMessage(ChatSocket cs,String out)        {                for(int i=0;i<vector.size();i++)                     {                         System.out.println(out + "==");                        ChatSocket csChatSocket= vector.get(i);                       if(!cs.equals(csChatSocket))//将发送该消息的客户端除外                             {                                 csChatSocket.out(out);                             }                     }            }}

3.Android端

public class SocketActivity extends Activity {    Button conBtn;    EditText ipText;    EditText point_text;    Button sendBtn;    EditText sendText;    TextView textView;    Socket clientSocket;    BufferedReader bfReader;    BufferedWriter bfWriter;    private String ipStr = "192.168.2.32";    private int ipStrProt = 2233;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.socket);                findViews();                 conBtn.setOnClickListener(new View.OnClickListener() {                        @Override                        public void onClick(View v) {                            ipStr = ipText.getText().toString();                            ipStrProt = Integer.parseInt(point_text.getText().toString());                                if (ipStr.equals("") || ipStrProt == 0 ){                                    Toast.makeText(SocketActivity.this,"请输入IP和端口号",Toast.LENGTH_SHORT).show();                                }else {                                    connect();                                }                            }                 });                 sendBtn.setOnClickListener(new View.OnClickListener() {                        @Override                        public void onClick(View v) {                                send();                            }                     });    }    private void findViews(){                conBtn = (Button)findViewById(R.id.con_btn);                sendBtn = (Button)findViewById(R.id.send_btn);                ipText = (EditText)findViewById(R.id.ip_text);                point_text = (EditText)findViewById(R.id.point_text);                sendText = (EditText)findViewById(R.id.send_text);                textView = (TextView)findViewById(R.id.content_text);             }    private void connect(){                     AsyncTask<Void,String,Void> reader = new AsyncTask<Void, String, Void>() {                             @Override                             protected Void doInBackground(Void... params) {                                     try {                                         Log.e("ip",ipStr + "-" + ipStrProt);                                         clientSocket = new Socket(ipStr,ipStrProt);                                        //客户端建立与服务端socket的连接,"10.62.37.152"为我的局域网ip地址,读者按照自己的ip地址进行相应修改                                         bfWriter = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));//                                       bfReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));                                         publishProgress("success");                                         while(clientSocket.isConnected() && !clientSocket.isClosed()){//isConnected 代表是否连接成功过                                             InputStream isRead = clientSocket.getInputStream();                                             // 缓冲区                                             byte[] buffer = new byte[isRead.available()];                                             // 读取缓冲区                                             isRead.read(buffer);                                             // 转换为字符串                                             String responseInfo = new String(buffer);                                             Log.e("Socket Server", responseInfo);                                             // 日志中输出                                             if (!responseInfo.equals("")){                                                 publishProgress(responseInfo);                                             }                                         }//                                         publishProgress("success");//                                             String line = "hello";//                                             while(true){//                                                 line = bfReader.readLine();//                                                 Log.e("message",line);//                                                 publishProgress(line);//接收从服务端转发来的消息//                                             }                                         } catch (Exception e) {                                         e.printStackTrace();                                            publishProgress("链接建立失败" + "--"+e.toString());                                         Log.e("SocketActivity",e.toString());                                         }                                        return  null;                                }                            @Override                         protected void onProgressUpdate(String... values) {                                if (values[0] == "success") {                                    Toast.makeText(SocketActivity.this, "链接建立成功",                                            Toast.LENGTH_SHORT).show();                                }                                 textView.append("别人说:" + values[0] + "\n");                                     super.onProgressUpdate(values);                                 }                        };                     reader.execute();             }    //发送消息给服务端         private void send(){                 try {                         textView.append("我说"+sendText.getText().toString()+"\n");                         bfWriter.write(sendText.getText().toString() + "\n");                         bfWriter.flush();                     } catch (IOException e) {                         Toast.makeText(getApplicationContext(),"无法建立连接",Toast.LENGTH_LONG).show();                         e.printStackTrace();                     }            }    private void end(Socket serverSocket){         /* * * * * * * * * * Socket 客户端读取服务器端响应数据 * * * * * * * * * */        try {            // serverSocket.isConnected 代表是否连接成功过            // 判断 Socket 是否处于连接状态            if(true == serverSocket.isConnected() && false == serverSocket.isClosed()) {                // 客户端接收服务器端的响应,读取服务器端向客户端的输入流                InputStream isRead = serverSocket.getInputStream();                // 缓冲区                byte[] buffer = new byte[isRead.available()];                // 读取缓冲区                isRead.read(buffer);                // 转换为字符串                String responseInfo = new String(buffer);                // 日志中输出                Log.e("Socket Server", responseInfo);            }            // 关闭网络            serverSocket.close();        }        catch (UnknownHostException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }    }}
<?xml version="1.0" encoding="utf-8"?>     <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"         xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"         android:layout_height="match_parent"         android:orientation="vertical">         <EditText             android:id="@+id/ip_text"             android:text="192.168.12.46"             android:hint="输入IP地址"             android:layout_width="match_parent"             android:layout_height="wrap_content" />         <EditText             android:id="@+id/point_text"             android:text="2223"             android:hint="输入端口号地址"             android:layout_width="match_parent"             android:layout_height="wrap_content" />         <Button             android:id="@+id/con_btn"            android:text="Connect"            android:layout_width="wrap_content"             android:layout_height="wrap_content" />         <TextView             android:layout_width="match_parent"             android:layout_height="280dp"             android:id="@+id/content_text"/>         <EditText             android:id="@+id/send_text"             android:layout_width="match_parent"             android:layout_height="wrap_content" />         <Button             android:text="send"             android:id="@+id/send_btn"             android:layout_width="match_parent"             android:layout_height="wrap_content" />     </LinearLayout>

4.遇到的问题

    可能你会觉得Socket很简单,是的,确实很简单,当时我也是觉得很简单的。很快就遇到问题了,客户端可以向服务端发消息,但是服务端发的消息客户端接收不到,通过调试发现在
bfReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));bfReader.readLine()

这里阻塞了,一直读不出来服务端的信息,后来通过自己的猜想,换一种方式读取接没问题了:

while(clientSocket.isConnected() && !clientSocket.isClosed()){//isConnected 代表是否连接成功过                                             InputStream isRead = clientSocket.getInputStream();                                             // 缓冲区                                             byte[] buffer = new byte[isRead.available()];                                             // 读取缓冲区                                             isRead.read(buffer);                                             // 转换为字符串                                             String responseInfo = new String(buffer);                                             Log.e("Socket Server", responseInfo);                                             // 日志中输出                                             if (!responseInfo.equals("")){                                                 publishProgress(responseInfo);                                             }                                         }

以上内容是小编给大家分享的Android Socket通信详解的相关知识,希望大家喜欢。

0 0
原创粉丝点击