Socket使用

https://github.com/townkoim/Socket.git
以爲爲demo路徑 (包含服務器端代碼以及客戶端代碼,基於TCP傳輸的demo)

Socket 的傳輸數據的兩種方式:
     1、TCP  可靠協議,假設服務器發送消息給客戶端,客戶端收到之後,會有一個迴應給服務器端,告訴它“我已經收到了”,如果服務器在設定的時間沒沒有收到客戶端的反饋,則認爲消息發送不成功,繼續發送 ,所以TCP協議是安全的,可靠協議,很少出現丟包的情況
     2、UDP 不可靠協議,服務器端只管發送數據給客戶端,無論你有沒有收到,都不會做處理, 一般用來做直播。視頻通過這些用的比較多
     

首先看服務器的代碼:

public class ServerSockt {
       //因爲可能不止一個客戶端,所以採用集合的方式來管理socket
       public static List<Socket> lists = Collections.synchronizedList( new ArrayList<Socket>());
       public static void main(String[] args) {
             try {
                  ServerSocket ss = new ServerSocket(8285);
                   while( true){
                        Socket s =ss.accept();
                         lists.add(s);
                         //開啓一個線程 接受與發送消息給客戶端
                         new Thread( new ServerThread(s)).start();
                  }
                  
            } catch (Exception e) {
                  
            }
      }
}

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;

public class ServerThread extends Thread {
       private Socket socket;
       private BufferedReader br;

       public ServerThread(Socket socket) throws Exception {
             super();
             this. socket = socket;
             //編碼一定要統一
             br = new BufferedReader( new InputStreamReader(socket.getInputStream(),"UTF-8" ));
      }
       @Override
       public void run() {
             super.run();
             try {
                  String msg;
                   while((msg= br.readLine())!= null){
                        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss" );//格式化日期
                         //將接收到的字符串讀取出來,加上日期返回給客戶端,編碼一定要統一
                        PrintStream ps = new PrintStream(socket .getOutputStream(), true,"UTF-8" );
                              ps.println( "服務器說還給你:" +msg+">>>>>" +df.format( new Date()));
                              System. out.println(msg);
                              ps.flush();
                  }
            } catch (Exception e) {
                  
            }
      }
}


注意一個細節!就是編碼問題,一定要統一流的編碼格式


Android客戶端的代碼

public class MainActivity extends AppCompatActivity {
    private EditText text; //文本框,要發送給服務器的數據
    private Button btnSocket;  //發送消息的按鈕
    private ListView listView; //消息列表的ListView
    private MsgAdapter adapter; //消息適配器
    private List<String> list = new ArrayList<>();//ListView的數據源
    private Socket socket = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        text = (EditText) findViewById(R.id.text);
        btnSocket = (Button) findViewById(R.id.button);
        listView = (ListView) findViewById(R.id.msgList);
        adapter = new MsgAdapter(MainActivity.this, list);
        listView.setAdapter(adapter);
        //開始的時候,我直接放在主線程,直接出現不能在主線程的工作的錯誤,於是開啓了一個線程
        new Thread(new Runnable() {
            @Override
            public void run() {
                socket();

            }
        }).start();
        //發送消息的按鈕,發送消息到服務器是異步的,所以也只能另開一個線程
        btnSocket.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        sendMsg();
                    }
                }).start();
            }
        });

    }

    /**
     * 初始化Socket
     */
    private void socket() {
        try {
            if (socket == null) {
                socket = new Socket("192.168.11.150", 8285);
            }
            receiveMsg();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 發送消息的方法
     */
    public void sendMsg() {
        PrintStream writer = null;
        try {
            String msg = "客戶端說:" + text.getText().toString();
            //此處一定要設置編碼的格式,一定要和服務器統一,否則會出現亂碼的情況
            writer = new PrintStream(socket.getOutputStream(), true, "UTF-8");
            writer.println(msg);
            writer.flush();
            list.add(msg);
            handler.sendEmptyMessage(0);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * 接收到來自服務器的消息
     */
    public void receiveMsg() {
        BufferedReader br = null;
        try {
            //此處一定要設置編碼的格式,一定要和服務器統一,否則會出現亂碼的情況
            br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
            String msg;
            while ((msg = br.readLine()) != null) {
                list.add(msg);
                handler.sendEmptyMessage(0);
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            adapter.notifyDataSetChanged();
        }
    };

}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章