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();
- }
- };
- }