android客户端与服务器端socket通信

2019-07-14 00:23发布


所谓的Socket通常称为套接字,用于描述IP地址和端口,是一个通信连的句柄。应用程序通过套接字向网络发送请求,或者应答网络请求。Socket套接字,其实就是Java对TCP/IP的实现,Socket和ServerSocket可以形象的比喻为插头和插座,ServerSocket插座提供电源,是服务端;Socket插头要得到电源,是客户端。Socket网络通讯传输数据的过程就好比插头获取插座电源的过程。 服务端:利用ServerSocket监听指定的端口,等待客户端的连接请求,客户端建立连接之后,产生会话,完成会话后,关闭连接。
客户端:利用Socket向网络上的某一个端口发出连接请求,一旦连接成功,产生会话,完成回话之后,关闭连接。
服务器端: package com.test.server; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketImpl; import com.sun.imageio.spi.InputStreamImageInputStreamSpi; /** * 构建服务器端 * * @author sjm * * */ public class Test implements Runnable { public static final String SERVERIP = "";// ip public static final int SERVERPORT = 8085;// 端口号 @Override public void run() { try { System.out.println("开始了,小伙~~~~"); ServerSocket socket = new ServerSocket(SERVERPORT); while (true) { Socket client = socket.accept();// 等待客户端接入,返回socket对象 System.out.println("等待客户端接入"); try { // 接收客户端消息 BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream())); // 返回给客户端消息 PrintWriter out = new PrintWriter( new BufferedWriter(new OutputStreamWriter(client.getOutputStream())), true); System.out.println("上面规定好接收和发送~~~~"); String str = in.readLine();// 开始读取客户端的消息 System.out.println("客户端发来的消息是什么呢 ======" + str); // 设置返回信息 if (str != null) { out.println("嗨,服务器接收到消息了,你是不是发送了:" + str + "?"); out.flush(); // 将客户端发送的消息保存到本地文件中 File file = new File("e://text.txt"); FileOutputStream fileOut = new FileOutputStream(file); byte[] bytes = str.getBytes(); for (int i = 0; i < bytes.length; i++) { fileOut.write(bytes[i]); } System.out.println("收到的消息是:" + str); } else { System.out.println("收到的消息为空"); } } catch (Exception e) { System.out.println("BufferedReader & PrintWriter error"); e.printStackTrace(); } finally { client.close(); System.out.println("关闭连接,结束~~~~~~~~~~~"); } } } catch (Exception e) { System.out.println("出错了"); e.printStackTrace(); } } /** * 开启服务器 * * @param args */ public static void main(String[] args) { new Thread(new Test()).start(); } }
客户端: package com.example.client; import android.support.v7.app.ActionBarActivity; import android.util.Log; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; import org.xml.sax.InputSource; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import junit.framework.Protectable; public class MainActivity extends ActionBarActivity { private static final String TAG = "com.example.client.MainActivity"; private Button btn = null; private TextView tv = null; private EditText edit = null; private static final String PORT = "192.168.1.100"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn = (Button) findViewById(R.id.btn); tv = (TextView) findViewById(R.id.tv); edit = (EditText) findViewById(R.id.edit); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // 开启子线程来进行ui线程的更新,不能在主线程中更新ui // 当在主线程中更新ui时,1、如果加上finally,会包空指针;2、如果不加,会报NetworkOnMainThreadException异常(网络请求在主线程中异常) new Thread(networkTask).start();// } }); } Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); // 接收handler中的消息 Bundle data = msg.getData(); String val = data.getString("value"); Log.i(TAG, "请求结果为-->" + val); // TODO :UI界面的更新等相关操作 setTitle("测试socket连接"); tv.setText(val); edit.setText("");// 清空文本框 } }; /** * 网络操作相关的子线程 */ Runnable networkTask = new Runnable() { @Override public void run() { // 开启一个子线程,进行网络操作,等待有返回结果,使用handler通知UI Socket socket = null; try { // InetAddress address = InetAddress.getByName(PORT);// // 主机地址:服务器ip socket = new Socket(PORT, 8085); System.out.println("4"); Log.e(TAG, "连接通了,主机地址为:" + PORT); // 通过PrintWriter 将消息发送到服务器 PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true); // 将输入框内容发送到服务器 String content = edit.getText().toString(); Log.e(TAG, "edit的内容:" + content); out.println(content); out.flush(); // 接收服务器消息 BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); // 读取服务器消息 String msg = in.readLine(); // 显示服务器消息到android界面 Message msg1 = new Message(); Bundle data = new Bundle(); data.putString("value", msg); msg1.setData(data); handler.sendMessage(msg1); } catch (UnknownHostException e) { Log.e(TAG, PORT + "服务器ip错误~~~"); } catch (IOException e) { Log.e(TAG, "网络连接出错,当前服务器ip为:" + PORT); e.printStackTrace(); } finally { try { socket.close(); } catch (IOException e) { Log.e(TAG, "ssss11111"); e.printStackTrace(); } } } }; } 有一个bug,服务器显示在android界面上的是乱码的,这个很好改的,不想改了~~~~