android socket多线程,Socket通信——加入多线程

实现一个简单的C/S聊天室

服务器端程序:

MyServer.java

import java.io.*;

import java.net.*;

import java.util.*;

//负责处理每个线程通信的线程类

class ServerThread implements Runnable

{

//定义当前线程所处理的Socket

Socket s = null;

//该线程所处理的Socket所对应的输入流

BufferedReader br = null;

public ServerThread(Socket s)

throws IOException

{

this.s = s;

//初始化该Socket对应的输入流

br = new BufferedReader(new InputStreamReader(

s.getInputStream() , "utf-8"));

}

public void run()

{

try

{

String content = null;

//采用循环不断从Socket中读取客户端发送过来的数据

while ((content = readFromClient()) != null)

{

System.out.println("---" + Arrays.toString(content.getBytes("utf-8")));

System.out.println("---" + content);

//遍历socketList中的每个Socket,

//将读到的内容向每个Socket发送一次

for (Iterator it = MyServer.socketList.iterator(); it.hasNext(); )

{

Socket s = it.next();

try{

OutputStream os = s.getOutputStream();

os.write((content + "\n").getBytes("utf-8"));

}

catch(SocketException e)

{

e.printStackTrace();

//删除该Socket。

it.remove();

System.out.println(MyServer.socketList);

}

}

}

}

catch (IOException e)

{

e.printStackTrace();

}

}

//定义读取客户端数据的方法

private String readFromClient()

{

try

{

return br.readLine();

}

//如果捕捉到异常,表明该Socket对应的客户端已经关闭

catch (IOException e)

{

e.printStackTrace();

//删除该Socket。

MyServer.socketList.remove(s);

}

return null;

}

}

public class MyServer

{

//定义保存所有Socket的ArrayList

public static ArrayList socketList

= new ArrayList();

public static void main(String[] args) throws IOException

{

ServerSocket ss = new ServerSocket(25000);

System.out.println("ss" );

while(true)

{

System.out.println("123" );

//此行代码会阻塞,将一直等待别人的连接

Socket s = ss.accept();

System.out.println("s!!!" );

socketList.add(s);

//每当客户端连接后启动一条ServerThread线程为该客户端服务

new Thread(new ServerThread(s)).start();

}

}

}

客户端程序:

主界面程序MainActivity.java

package com.supermap.experiment;

import android.app.Activity;

import android.os.Bundle;

import android.os.Handler;

import android.os.Message;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.EditText;

import android.widget.TextView;

public class MainActivity extends Activity

{

//定义界面上的两个文本框

EditText input;

TextView show;

//定义界面上的一个按钮

Button send;

Handler handler;

//定义与服务器通信的子线程

ClientThread clientThread;

@Override

public void onCreate(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

input = (EditText) findViewById(R.id.input);

send = (Button) findViewById(R.id.send);

show = (TextView) findViewById(R.id.show);

handler = new Handler()

{

@Override

public void handleMessage(Message msg)

{

//如果消息来自于子线程

if (msg.what == 0x123)

{

//将读取的内容追加显示在文本框中

show.append("\n" + msg.obj.toString());

}

}

};

clientThread = new ClientThread(handler);

//客户端启动ClientThread线程创建网络连接、读取来自服务器的数据

new Thread(clientThread).start();

send.setOnClickListener(new OnClickListener()

{

@Override

public void onClick(View v)

{

try

{

//当用户按下发送按钮后,将用户输入的数据封装成Message

//然后发送给子线程的Handler

Message msg = new Message();

msg.what = 0x345;

msg.obj = input.getText().toString();

clientThread.revHandler.sendMessage(msg);

//清空input文本框

input.setText("");

}

catch (Exception e)

{

e.printStackTrace();

}

}

});

}

}

子线程程序ClientThread.java

package com.supermap.experiment;

import android.os.Handler;

import android.os.Looper;

import android.os.Message;

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.OutputStream;

import java.net.Socket;

import java.net.SocketTimeoutException;

public class ClientThread implements Runnable

{

private Socket s;

//定义向UI线程发送消息的Handler对象

private Handler handler;

//定义接收UI线程的消息的Handler对象

public Handler revHandler;

//该线程所处理的Socket所对应的输入流

BufferedReader br = null;

OutputStream os = null;

public ClientThread(Handler handler)

{

this.handler = handler;

}

public void run()

{

try

{

s = new Socket("192.168.7.38", 25000);

br = new BufferedReader(new InputStreamReader(

s.getInputStream()));

os = s.getOutputStream();

//启动一条子线程来读取服务器响应的数据

new Thread()

{

@Override

public void run()

{

String content = null;

//不断读取Socket输入流中的内容

try

{

while ((content = br.readLine()) != null)

{

//每当读到来自服务器的数据之后,发送消息通知程序

//界面显示该数据

Message msg = new Message();

msg.what = 0x123;

msg.obj = content;

handler.sendMessage(msg);

}

}

catch (IOException e)

{

e.printStackTrace();

}

}

}.start();

//为当前线程初始化Looper

Looper.prepare();

//创建revHandler对象

revHandler = new Handler()

{

@Override

public void handleMessage(Message msg)

{

//接收到UI线程中用户输入的数据

if (msg.what == 0x345)

{

//将用户在文本框内输入的内容写入网络

try

{

os.write((msg.obj.toString() + "\r\n")

.getBytes("utf-8"));

}

catch (Exception e)

{

e.printStackTrace();

}

}

}

};

//启动Looper

Looper.loop();

}

catch (SocketTimeoutException e1)

{

System.out.println("网络连接超时!!");

}

catch (Exception e)

{

e.printStackTrace();

}

}

}

页面布局文件activity_main.xml

android:orientation="vertical"

android:layout_width="match_parent"

android:layout_height="match_parent">

android:orientation="horizontal"

android:layout_width="match_parent"

android:layout_height="wrap_content">

android:id="@+id/input"

android:layout_width="280dp"

android:layout_height="wrap_content" />

android:id="@+id/send"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:paddingLeft="8dp"

android:text="@string/send"/>

android:id="@+id/show"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:gravity="top"

android:background="#ffff"

android:textSize="14dp"

android:textColor="#f000"/>

清单文件AndroidManifest.xml

package="com.supermap.experiment" >

android:allowBackup="true"

android:icon="@mipmap/ic_launcher"

android:label="@string/app_name"

android:theme="@style/AppTheme" >

android:name=".MainActivity"

android:label="@string/app_name" >

实验效果:

运行MyServer类,看到服务器一直处于等待状态,等待来自客户端的请求。

84da1bebfdb6f9d0dec6bcc9959b658e.png

再运行客户端,将看到程序输出:“圣诞节快乐!”,表示客户端和服务器连接成功,粗略实现了C/S结构聊天室的功能。

d15764f95690cdb0e79e4e5e938628e1.png

ecefa13fae958aed0d7af9501d7f5738.png

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值