废话不多说直接上代码
//权限 引入
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!--允许应用程序改变网络状态-->
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<!--允许应用程序改变WIFI连接状态-->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<!--允许应用程序访问有关的网络信息-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!--允许应用程序访问WIFI网卡的网络信息-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<!--允许应用程序完全使用网络-->
<uses-permission android:name="android.permission.INTERNET"/>
获取当前ip地址
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;
public class NetWorkUtil {
public static String getIPAddress(Context context) {
NetworkInfo info = ((ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();
if (info != null && info.isConnected()) {
if (info.getType() == ConnectivityManager.TYPE_MOBILE) {//当前使用2G/3G/4G网络
try {
//Enumeration<NetworkInterface> en=NetworkInterface.getNetworkInterfaces();
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {
return inetAddress.getHostAddress();
}
}
}
} catch (SocketException e) {
e.printStackTrace();
}
} else if (info.getType() == ConnectivityManager.TYPE_WIFI) {//当前使用无线网络
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
String ipAddress = intIP2StringIP(wifiInfo.getIpAddress());//得到IPV4地址
return ipAddress;
}
} else {
//当前无网络连接,请在设置中打开网络
}
return null;
}
/**
* 将得到的int类型的IP转换为String类型
*
* @param ip
* @return
*/
public static String intIP2StringIP(int ip) {
return (ip & 0xFF) + "." +
((ip >> 8) & 0xFF) + "." +
((ip >> 16) & 0xFF) + "." +
(ip >> 24 & 0xFF);
}
}
服务端
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class TcpServerActivity extends Activity implements OnClickListener {
private final String TAG = "TcpServerActivity";
private TextView mServerState, mTvReceive;
private TextView ipTextView = null;
private TextView nameTextView = null;
//定义一个ConnectivityManager对象
private ConnectivityManager mConnectivityManager = null;
//定义一个NetworkInfo对象
private NetworkInfo mActiveNetInfo = null;
private Button mBtnSet, mBtnStrat, mBtnSend;
private EditText mEditMsg;
private ServerSocket mServerSocket;
public Socket mSocket;
private SharedPreferences mSharedPreferences;
private final int DEFAULT_PORT = 8086;
private int mServerPort; //服务端端口
private static final String SERVER_PORT = "server_port";
private static final String SERVER_MESSAGETXT = "server_msgtxt";
private OutputStream mOutStream;
private InputStream mInStream;
private SocketAcceptThread mAcceptThread;
private SocketReceiveThread mReceiveThread;
private HandlerThread mHandlerThread;
//子线程中的Handler实例。
private Handler mSubThreadHandler;
private final int STATE_CLOSED = 1;
private final int STATE_ACCEPTING= 2;
private final int STATE_CONNECTED = 3;
private final int STATE_DISCONNECTED = 4;
private int mSocketConnectState = STATE_CLOSED;
private String mRecycleMsg;
private static final int MSG_TIME_SEND = 1;
private static final int MSG_SOCKET_CONNECT = 2;
private static final int MSG_SOCKET_DISCONNECT = 3;
private static final int MSG_SOCKET_ACCEPTFAIL = 4;
private static final int MSG_RECEIVE_DATA = 5;
private static final int MSG_SEND_DATA = 6;
@SuppressLint("HandlerLeak")
private Handler mHandler = new Handler(){
public void handleMessage(Message msg) {
switch(msg.what){
case MSG_TIME_SEND:
writeMsg(mRecycleMsg);
break;
case MSG_SOCKET_CONNECT:
mSocketConnectState = STATE_CONNECTED;
mServerState.setText(R.string.state_connected);
mReceiveThread = new SocketReceiveThread();
mReceiveThread.start();
break;
case MSG_SOCKET_DISCONNECT:
mSocketConnectState = STATE_DISCONNECTED;
mServerState.setText(R.string.state_disconect_accept);
startAccept();
break;
case MSG_SOCKET_ACCEPTFAIL:
startAccept();
break;
case MSG_RECEIVE_DATA:
String text = mTvReceive.getText().toString() +"\r\n" + (String)msg.obj;
mTvReceive.setText(text);
break;
default:
break;
}
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tcp_server);
mServerState = (TextView) findViewById(R.id.serverState);
mBtnSet = (Button)findViewById(R.id.bt_server_set);
mBtnStrat = (Button)findViewById(R.id.bt_server_start);
mBtnSend = (Button)findViewById(R.id.bt_server_send);
mEditMsg = (EditText)findViewById(R.id.server_sendMsg);
mTvReceive = (TextView) findViewById(R.id.server_receive);
ipTextView = (TextView)findViewById(R.id.ipTextView);
ipTextView.setText(NetWorkUtil.getIPAddress(TcpServerActivity.this));
mBtnSet.setOnClickListener(this);
mBtnStrat.setOnClickListener(this);
mBtnSend.setOnClickListener(this);
mSharedPreferences = getSharedPreferences("setting", Context.MODE_PRIVATE);
mServerPort = mSharedPreferences.getInt(SERVER_PORT, DEFAULT_PORT);
initHandlerThraed();
}
@Override
protected void onResume() {
super.onResume();
if(mSocketConnectState == STATE_CLOSED)
mServerState.setText(R.string.state_closed);
else if(mSocketConnectState == STATE_CONNECTED)
mServerState.setText(R.string.state_connected);
else if(mSocketConnectState == STATE_DISCONNECTED || mSocketConnectState == STATE_ACCEPTING)
mServerState.setText(R.string.state_disconect_accept);
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy");
//退出HandlerThread的Looper循环。
mHandlerThread.quit();
closeConnect();
if(mServerSocket != null){
try {
mServerSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.bt_server_set:
set();
break;
case R.id.bt_server_start:
startServer();
break;
case R.id.bt_server_send:
sendTxt();
break;
default:
break;
}
}
private void set(){
View setview = LayoutInflater.from(this).inflate(R.layout.dialog_server, null);
final EditText editport = (EditText)setview.findViewById(R.id.server_port);
Button ensureBtn = (Button)setview.findViewById(R.id.server_ok);
editport.setText(mSharedPreferences.getInt(SERVER_PORT, 8086) + "");
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setView(setview); //设置dialog显示一个view
final AlertDialog dialog = builder.show(); //dialog显示
ensureBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
String port = editport.getText().toString();
if(port != null && port.length() >0){
mServerPort = Integer.parseInt(port);
}
SharedPreferences.Editor editor=mSharedPreferences.edit();
editor.putInt(SERVER_PORT, mServerPort);
editor.commit();
dialog.dismiss(); //dialog消失
}
});
}
private void startServer() {
if(mSocketConnectState != STATE_CLOSED) return;
try {
//开启服务、指定端口号
mServerSocket = new ServerSocket(mServerPort);
} catch (IOException e) {
e.printStackTrace();
mSocketConnectState = STATE_DISCONNECTED;
Toast.makeText(this, "服务开启失败", Toast.LENGTH_SHORT).show();
return;
}
startAccept();
mServerState.setText(getString(R.string.state_opened));
Toast.makeText(this, "服务开启", Toast.LENGTH_SHORT).show();
}
private void startAccept(){
mSocketConnectState = STATE_ACCEPTING;
mAcceptThread = new SocketAcceptThread();
mAcceptThread.start();
}
private void sendTxt(){
if(mRecycleMsg != null){
//每次点击发送按钮发送数据,将之前的定时发送移除。
mHandler.removeMessages(MSG_TIME_SEND);
mRecycleMsg = null;
}
if(mSocket == null){
Toast.makeText(this, "没有客户端连接", Toast.LENGTH_SHORT).show();
return;
}
String str = mEditMsg.getText().toString();
if(str.length() == 0)
return;
Message msg = new Message();
msg.what = MSG_SEND_DATA;
msg.obj = str;
mSubThreadHandler.sendMessage(msg);
}
private void writeMsg(String msg){
if(msg.length() == 0 || mOutStream == null)
return;
try {
mOutStream.write(msg.getBytes());//发送
mOutStream.flush();
}catch (Exception e) {
e.printStackTrace();
}
}
public void closeConnect(){
try {
if (mOutStream != null) {
mOutStream.close();
}
if (mInStream != null) {
mInStream.close();
}
if(mSocket != null){
mSocket.close(); //关闭socket
mSocket = null;
}
} catch (IOException e) {
e.printStackTrace();
}
if(mReceiveThread != null){
mReceiveThread.threadExit();
mReceiveThread = null;
}
}
class SocketAcceptThread extends Thread{
@Override
public void run() {
try {
//等待客户端的连接,Accept会阻塞,直到建立连接,
//所以需要放在子线程中运行。
mSocket = mServerSocket.accept();
//获取输入流
mInStream = mSocket.getInputStream();
//获取输出流
mOutStream = mSocket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
mHandler.sendEmptyMessage(MSG_SOCKET_ACCEPTFAIL);
return;
}
Log.i(TAG, "accept success");
mHandler.sendEmptyMessage(MSG_SOCKET_CONNECT);
}
}
class SocketReceiveThread extends Thread{
private boolean threadExit = false;
public void run(){
byte[] buffer = new byte[1024];
while(threadExit == false){
try { //读取数据,返回值表示读到的数据长度。-1表示结束
int count = mInStream.read(buffer);
if(count == -1){
Log.i(TAG, "read read -1");
mHandler.sendEmptyMessage(MSG_SOCKET_DISCONNECT);
break;
}else{
String receiveData;
receiveData = new String(buffer, 0, count);
Log.i(TAG, "read buffer:"+receiveData+",count="+count);
Message msg = new Message();
msg.what = MSG_RECEIVE_DATA;
msg.obj = receiveData;
mHandler.sendMessage(msg);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
void threadExit(){
threadExit = true;
}
}
private void initHandlerThraed() {
//创建HandlerThread实例
mHandlerThread = new HandlerThread("handler_thread");
//开始运行线程
mHandlerThread.start();
//获取HandlerThread线程中的Looper实例
Looper loop = mHandlerThread.getLooper();
//创建Handler与该线程绑定。
mSubThreadHandler = new Handler(loop){
public void handleMessage(Message msg) {
Log.i(TAG, "mSubThreadHandler handleMessage thread:"+Thread.currentThread());
switch(msg.what){
case MSG_SEND_DATA:
writeMsg((String)msg.obj);
break;
default:
break;
}
};
};
}
}
布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/server_lin"
android:layout_alignParentTop="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="@+id/serverState"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/layout_top_margin"
android:gravity="center"
android:text="@string/state"
android:textSize="@dimen/title_size" />
<LinearLayout
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_marginLeft="20dp"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="本地IP地址:"/>
<TextView
android:id="@+id/ipTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" "
android:textSize="20dp"
/>
</LinearLayout>
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_marginTop="@dimen/layout_top_margin"
android:layout_marginLeft="@dimen/left_right_margin"
android:layout_marginRight="@dimen/left_right_margin"
android:orientation="horizontal">
<Button
android:id="@+id/bt_server_set"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/set" />
<Button
android:id="@+id/bt_server_start"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/start_server" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/left_right_margin"
android:layout_marginRight="@dimen/left_right_margin"
android:orientation="horizontal">
<EditText
android:id="@+id/server_sendMsg"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:hint="@string/send_hint" />
<Button android:id="@+id/bt_server_send"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/send"/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="0.2dp"
android:background="#000"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="服务端返回信息如下:"/>
</LinearLayout>
<ScrollView
android:id="@+id/server_scroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/server_lin"
android:layout_alignParentBottom="true">
<TextView
android:id="@+id/server_receive"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/left_right_margin"
android:layout_marginRight="@dimen/left_right_margin"
android:textSize="20dp" />
</ScrollView>
</RelativeLayout>
效果图
设置弹窗 dialog_server.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="@string/port"
android:textSize="@dimen/dialog_txt_size"/>
<EditText
android:id="@+id/server_port"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:inputType="number"
android:digits="0123456789"
android:ems="10"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:visibility="gone" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/message_mode"
android:gravity="center"
android:layout_weight="1"
android:textSize="@dimen/dialog_txt_size"/>
<RadioGroup
android:id="@+id/display_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="2"
android:orientation="horizontal" >
<RadioButton
android:id="@+id/server_modetxt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="@string/txt" />
<RadioButton
android:id="@+id/server_modehex"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hex" />
</RadioGroup>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:visibility="gone" >
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="@string/send_ontime" />
<EditText
android:id="@+id/server_timeinterval"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:inputType="number"
android:digits="0123456789"
android:ems="10"
android:hint="@string/hint_time" >
</EditText>
</LinearLayout>
<Button
android:id="@+id/server_ok"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/ok" />
</LinearLayout>
效果
以上就socket服务端代码
下面就是客户端代码了
import android.os.Bundle;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class TcpClientActivity extends Activity implements View.OnClickListener {
private final String TAG = "TcpClientActivity";
private Button mBtnSet, mBtnConnect, mBtnSend;
private EditText mEditMsg;
private TextView mClientState, mTvReceive;
public Socket mSocket;
private SharedPreferences mSharedPreferences;
private final int DEFAULT_PORT= 8086;
private String mIpAddress; //服务端ip地址
private int mClientPort; //端口,默认为8086,可以进行设置
private static final String IP_ADDRESS = "ip_address";
private static final String CLIENT_PORT = "client_port";
private static final String CLIENT_MESSAGETXT = "client_msgtxt";
private OutputStream mOutStream;
private InputStream mInStream;
private SocketConnectThread mConnectThread;
private SocketReceiveThread mReceiveThread;
private HandlerThread mHandlerThread;
//子线程中的Handler实例。
private Handler mSubThreadHandler;
private final int STATE_DISCONNECTED = 1;
private final int STATE_CONNECTING= 2;
private final int STATE_CONNECTED = 3;
private int mSocketConnectState = STATE_DISCONNECTED;
private static final int MSG_TIME_SEND = 1;
private static final int MSG_SOCKET_CONNECT = 2;
private static final int MSG_SOCKET_DISCONNECT = 3;
private static final int MSG_SOCKET_CONNECTFAIL = 4;
private static final int MSG_RECEIVE_DATA = 5;
private static final int MSG_SEND_DATA = 6;
private Handler mHandler = new Handler(){
public void handleMessage(Message msg) {
switch(msg.what){
case MSG_TIME_SEND:
break;
case MSG_SOCKET_CONNECT:
mSocketConnectState = STATE_CONNECTED;
mClientState.setText(R.string.state_connected);
mBtnConnect.setText(R.string.disconnect);
mReceiveThread = new SocketReceiveThread();
mReceiveThread.start();
break;
case MSG_SOCKET_DISCONNECT:
mClientState.setText(R.string.state_disconected);
mBtnConnect.setText(R.string.connect);
mSocketConnectState = STATE_DISCONNECTED;
closeConnection();
break;
case MSG_SOCKET_CONNECTFAIL:
mSocketConnectState = STATE_DISCONNECTED;
mBtnConnect.setText(R.string.connect);
mClientState.setText(R.string.state_connect_fail);
break;
case MSG_RECEIVE_DATA:
String text = mTvReceive.getText().toString() +"\r\n" + (String)msg.obj;
mTvReceive.setText(text);
break;
default:
break;
}
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tcp_client);
mBtnSet = (Button)findViewById(R.id.bt_client_set);
mBtnConnect = (Button)findViewById(R.id.bt_client_connect);
mBtnSend = (Button)findViewById(R.id.bt_client_send);
mEditMsg = (EditText)findViewById(R.id.client_sendMsg);
mClientState = (TextView) findViewById(R.id.client_state);
mTvReceive = (TextView) findViewById(R.id.client_receive);
mBtnSet.setOnClickListener(this);
mBtnConnect.setOnClickListener(this);
mBtnSend.setOnClickListener(this);
mSharedPreferences = getSharedPreferences("setting", Context.MODE_PRIVATE);
//获取保存的ip地址、客户端端口号
mIpAddress = mSharedPreferences.getString(IP_ADDRESS, null);
mClientPort = mSharedPreferences.getInt(CLIENT_PORT, DEFAULT_PORT);
initHandlerThraed();
}
@Override
protected void onResume() {
super.onResume();
if(mSocketConnectState == STATE_CONNECTED){
mBtnConnect.setText(R.string.disconnect);
mClientState.setText(R.string.state_connected);
}else if(mSocketConnectState == STATE_DISCONNECTED){
mBtnConnect.setText(R.string.connect);
mClientState.setText(R.string.state_disconected);
}
else if(mSocketConnectState == STATE_CONNECTING){
mClientState.setText(R.string.state_connecting);
mClientState.setText(R.string.state_connected);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
//退出HandlerThread的Looper循环。
mHandlerThread.quit();
closeConnection();
}
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.bt_client_set:
set();
break;
case R.id.bt_client_connect:
if(mSocketConnectState == STATE_CONNECTED){
closeConnection();
}else{
startConnect();
}
break;
case R.id.bt_client_send:
sendTxt();
break;
default:
break;
}
}
private void set(){
View setview = LayoutInflater.from(this).inflate(R.layout.dialog_client, null);
final EditText ipAddress = (EditText) setview.findViewById(R.id.edtt_ipaddress);
final EditText editport = (EditText)setview.findViewById(R.id.client_port);
Button ensureBtn = (Button)setview.findViewById(R.id.client_ok);
ipAddress.setText(mSharedPreferences.getString(IP_ADDRESS, null));
editport.setText(mSharedPreferences.getInt(CLIENT_PORT, 8086) + "");
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setView(setview); //设置dialog显示一个view
final AlertDialog dialog = builder.show(); //dialog显示
ensureBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
String port = editport.getText().toString();
mIpAddress = ipAddress.getText().toString();
if(port != null && port.length() >0){
mClientPort = Integer.parseInt(port);
}
SharedPreferences.Editor editor=mSharedPreferences.edit();
editor.putString(IP_ADDRESS, mIpAddress);
editor.putInt(CLIENT_PORT, mClientPort);
editor.commit();
dialog.dismiss(); //dialog消失
}
});
}
private void startConnect() {
Log.i(TAG,"startConnect");
if(mIpAddress == null || mIpAddress.length() == 0){
Toast.makeText(this, "请设置ip地址", Toast.LENGTH_LONG).show();
return;
}
if(mSocketConnectState != STATE_DISCONNECTED) return;
mConnectThread = new SocketConnectThread();
mConnectThread.start();
mSocketConnectState = STATE_CONNECTING;
mClientState.setText(R.string.state_connecting);
}
private void sendTxt(){
if(mSocket == null){
Toast.makeText(this, "没有连接", Toast.LENGTH_SHORT).show();
return;
}
String str = mEditMsg.getText().toString();
if(str.length() == 0)
return;
Message msg = new Message();
msg.what = MSG_SEND_DATA;
msg.obj = str;
mSubThreadHandler.sendMessage(msg);
}
private void writeMsg(String msg){
Log.i(TAG, "writeMsg msg="+msg);
if(msg.length() == 0 || mOutStream == null)
return;
try {
mOutStream.write(msg.getBytes());//发送
mOutStream.flush();
}catch (Exception e) {
e.printStackTrace();
}
}
public void closeConnection(){
try {
if (mOutStream != null) {
mOutStream.close(); //关闭输出流
mOutStream = null;
}
if (mInStream != null) {
mInStream.close(); //关闭输入流
mInStream = null;
}
if(mSocket != null){
mSocket.close(); //关闭socket
mSocket = null;
}
} catch (IOException e) {
e.printStackTrace();
}
if(mReceiveThread != null){
mReceiveThread.threadExit();
mReceiveThread = null;
}
mSocketConnectState = STATE_DISCONNECTED;
mBtnConnect.setText(R.string.connect);
mClientState.setText(R.string.state_disconected);
}
class SocketConnectThread extends Thread{
public void run(){
try {
//连接服务端,指定服务端ip地址和端口号。
mSocket = new Socket(mIpAddress,mClientPort);
if(mSocket != null){
//获取输出流、输入流
mOutStream = mSocket.getOutputStream();
mInStream = mSocket.getInputStream();
}
} catch (Exception e) {
e.printStackTrace();
mHandler.sendEmptyMessage(MSG_SOCKET_CONNECTFAIL);
return;
}
Log.i(TAG,"connect success");
mHandler.sendEmptyMessage(MSG_SOCKET_CONNECT);
}
}
class SocketReceiveThread extends Thread{
private boolean threadExit;
public SocketReceiveThread() {
threadExit = false;
}
public void run(){
byte[] buffer = new byte[1024];
while(threadExit == false){
try {
//读取数据,返回值表示读到的数据长度。-1表示结束
int count = mInStream.read(buffer);
if( count == -1){
Log.i(TAG, "read read -1");
mHandler.sendEmptyMessage(MSG_SOCKET_DISCONNECT);
break;
}else{
String receiveData = new String(buffer, 0, count);
Log.i(TAG, "read buffer:"+receiveData+",count="+count);
Message msg = new Message();
msg.what = MSG_RECEIVE_DATA;
msg.obj = receiveData;
mHandler.sendMessage(msg);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
void threadExit(){
threadExit = true;
}
}
private void initHandlerThraed() {
//创建HandlerThread实例
mHandlerThread = new HandlerThread("handler_thread");
//开始运行线程
mHandlerThread.start();
//获取HandlerThread线程中的Looper实例
Looper loop = mHandlerThread.getLooper();
//创建Handler与该线程绑定。
mSubThreadHandler = new Handler(loop){
public void handleMessage(Message msg) {
Log.i(TAG, "mSubThreadHandler handleMessage thread:"+Thread.currentThread());
switch(msg.what){
case MSG_SEND_DATA:
writeMsg((String)msg.obj);
break;
default:
break;
}
};
};
}
}
布局代码
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/client_lin"
android:layout_alignParentTop="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="@+id/client_state"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_marginTop="@dimen/layout_top_margin"
android:text="@string/state"
android:textSize="@dimen/title_size" />
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_marginTop="@dimen/layout_top_margin"
android:layout_marginLeft="@dimen/left_right_margin"
android:layout_marginRight="@dimen/left_right_margin"
android:orientation="horizontal">
<Button
android:id="@+id/bt_client_set"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/set" />
<Button
android:id="@+id/bt_client_connect"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/connect" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/left_right_margin"
android:layout_marginRight="@dimen/left_right_margin"
android:orientation="horizontal">
<EditText
android:id="@+id/client_sendMsg"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:hint="@string/send_hint" />
<Button android:id="@+id/bt_client_send"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/send"/>
</LinearLayout>
</LinearLayout>
<ScrollView
android:id="@+id/scrollView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/client_lin"
android:layout_alignParentBottom="true">
<TextView
android:id="@+id/client_receive"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/left_right_margin"
android:layout_marginRight="@dimen/left_right_margin"
android:textSize="20sp" />
</ScrollView>
</RelativeLayout>
效果
设置弹窗布局 dialog_client.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="@string/server_ip"
android:textSize="@dimen/dialog_txt_size"/>
<EditText
android:id="@+id/edtt_ipaddress"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:ems="10"
android:hint="格式:10.10.4.11"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="@string/port"
android:textSize="@dimen/dialog_txt_size"/>
<EditText
android:id="@+id/client_port"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:inputType="number"
android:hint="8086"
android:digits="0123456789"
android:ems="10"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:visibility="gone" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/message_mode"
android:gravity="center"
android:layout_weight="1"
android:textSize="@dimen/dialog_txt_size"/>
<RadioGroup
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="horizontal" >
<RadioButton
android:id="@+id/client_modetxt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="@string/txt" />
<RadioButton
android:id="@+id/client_modehex"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hex" />
</RadioGroup>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:visibility="gone" >
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="@string/send_ontime" />
<EditText
android:id="@+id/client_timeinterval"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:inputType="number"
android:digits="0123456789"
android:ems="10"
android:hint="@string/hint_time" >
</EditText>
</LinearLayout>
<Button
android:id="@+id/client_ok"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/ok" />
</LinearLayout>
效果图
以上就是socket客户端和服务端全部代码,希望对你有帮助