1.TCP多线程原理图

2.实现方法

(1)服务器端

(2)客户端

3.java后台代码

主界面

package com.lucky.test50socket2;

import android.annotation.SuppressLint;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView; public class MainActivity extends AppCompatActivity {
EditText editText;
TextView textView2;
Button button1;
ClientThread clientThread; //handler实现页面与Socket的交互,handler获取ClientThread中发送的message
@SuppressLint("HandlerLeak")
Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
if(msg.what==0x01){
textView2.setText(msg.obj.toString());
}
}
}; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText=findViewById(R.id.editText);
textView2=findViewById(R.id.textView2);
button1=findViewById(R.id.button);
clientThread=new ClientThread(handler); //实例化ClientThread
new Thread(clientThread).start(); //开启客户端的线程
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Message message=new Message(); //实例化一个message
message.what=0x02; //设置message的代号
message.obj=editText.getText().toString();//设置message的内容
ClientThread.handlerrev.handleMessage(message); //调用ClientThread的成员对象的方法,向服务器发送消息
}
}); }
}

服务器

package com.lucky.myserver;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List; public class Myserver {
public static List<Socket> list; //定义一个存放socket的集合
public static void main(String[] args) throws IOException {
ServerSocket serverSocket=new ServerSocket(30004); //实例化一个服务器套接字
//while设置为死循环,等待客户端的socket请求的到来
while (true){
Socket socket=serverSocket.accept(); //获取套接字
list=new ArrayList<>();
list.add(socket);
ServerThead serverThead=new ServerThead(socket); //调用自建的ServerThead
new Thread(serverThead).start(); //启动线程
}
}
}

服务器线程

package com.lucky.myserver;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket; public class ServerThead implements Runnable {
private Socket socket;
InputStream inputStream; //输入流
OutputStream outputStream;//输出流
BufferedReader bufferedReader;
//构造方法
public ServerThead(Socket socket) throws IOException {
this.socket=socket;
inputStream=socket.getInputStream(); //获取输入流
bufferedReader=new BufferedReader(new InputStreamReader(inputStream,"utf-8")); } @Override
public void run() {
String str;
while ((str=readData())!=null){
for (Socket socket1 : Myserver.list) {
try {
outputStream=socket1.getOutputStream();
PrintStream printStream=new PrintStream(outputStream);
printStream.println(socket.getInetAddress()+":"+str);
} catch (IOException e) {
e.printStackTrace();
}
}
}
} private String readData(){
try {
return bufferedReader.readLine();
} catch (IOException e) {
Myserver.list.remove(socket); //删除套接字,避免占用内存
return null;
}
}
}

客户端

package com.lucky.test50socket2;

import android.annotation.SuppressLint;
import android.os.Looper;
import android.os.Message; import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.logging.Handler; public class ClientThread implements Runnable {
android.os.Handler handler1; //天坑:注意要导入android.os.Handler,handler要两种类型
InputStream inputStream;
OutputStream outputStream;
BufferedReader bufferedReader;
static android.os.Handler handlerrev; //构造方法
public ClientThread(android.os.Handler handler){
this.handler1=handler;
} @SuppressLint("HandlerLeak")
@Override
public void run() {
try {
Socket socket=new Socket("192.168.228.2",30004); //连接服务器
inputStream=socket.getInputStream();//实例化输入流
bufferedReader=new BufferedReader(new InputStreamReader(inputStream,"GBK"));
new Thread(){
@Override
public void run() {
String string;
try {
while ((string=bufferedReader.readLine())!=null){
Message message=new Message(); //实例化一个消息,通过handler发送到前台
message.what=0x01; //数据的代号
message.obj=string; //发送的数据
//信息回传给主线程(主界面)显示
handler1.sendMessage(message);
}
}catch (IOException e){
e.printStackTrace();
}
}
}.start();
/*
* 说明:如果要在非主线程中创建Handler对象,首先需要使用Looper类的prepare()方法来初始化一个Looper对象,
* 然后创建Handler对象,再使用Looper类的loop()方法启动Looper,从消息队列中获取和处理消息。
*/
Looper.prepare(); //准备handler
outputStream=socket.getOutputStream();//实例化输出流
handlerrev=new android.os.Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if(msg.what==0x02){ //根据msg是否是需要发送的消息,若是,执行以下操作
String str=msg.obj.toString();
PrintStream printStream=new PrintStream(outputStream);
printStream.println(str); //将消息数据发送到服务器
}
}
};
Looper.loop(); //这句代码可以理解为循环执行run方法(最外层的run)
} catch (IOException e) {
e.printStackTrace();
}
}
}

最新文章

  1. Codeforces Round #363 (Div. 2)
  2. jQuery的deferred对象详解(一)
  3. linux网卡速率和双工模式的配置
  4. BZOJ 3240 矩阵游戏
  5. 01.Net入门知识
  6. Vc6.0打开该文件坠毁
  7. Java-byte[]与16进制字符串互转
  8. Linux下的Mysql数据库备份+还原
  9. Node_初步了解(3)回调,作用域,上下文
  10. pytho学习笔记---编码
  11. Swift 编程语言【转载+整理】
  12. hdu 1542 Atlantis (线段树扫描线)
  13. mysql处理特殊字符
  14. 坐标转换convertRect
  15. day04(权限修饰符,内部类,局部内部类,匿名内部类)
  16. 【Android】4.0 Android项目的基本结构
  17. intelliJ IDEA 怎么添加本地的idea web项目
  18. JVM内存分配及GC简述
  19. java多线程学习三
  20. Django——admin管理工具

热门文章

  1. Subscript &amp; Inheritance
  2. Python_13-Office文件数据操作
  3. nohup 无发后台运行
  4. (一)maven的安装
  5. spring aop自动代理xml配置
  6. Java中迭代Map的方法
  7. Luogu 3350 [ZJOI2016]旅行者
  8. 再谈JavaScript的closure--JavaScript 闭包
  9. 常用eclipse插件
  10. Alpha项目复审