Android Sockdet

1.简介

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

2.服务器端

    直接上代码
public class MyServerSocket {
    private Vector vector=new Vector();//存放所有的客户端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 vector;
         public ChatSocket(Socket s,Vectorvector)
         {
                 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;iout.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 reader = new AsyncTask() {
                             @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();
        }
    }


}

     <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通信详解的相关知识,希望大家喜欢。

你可能感兴趣的:(Android开发,android,socket)