Android Socket通信
- 什么是Socket
是一种抽象层,简单来说,Socket提供了程序内部与外界通讯的端口,并为双方提供了数据传输通道。 - Socket分类
根据不同的底层协议,Socket的实现是多样化的。我了解的是基于TCP/IP协议族,在这个协议族中主要的Socket类型为流套接字和数据套接字。流套接字将TCP作为其端对端协议,提供了一个值得信赖的字节流服务。数据报套接字使用UDP协议,提供数据打包发送服务。 - Socket基本实现原理
服务端首先声明一个Serversocket对象并且指定其端口号,然后调用accept()方法接受客户端数据。accept()方法在没接收到数据处于堵塞状态,一旦接受到数据,通过inputstream读取接受数据。
客户端创建一个Socket对象,指定服务器端IP和端口号
Socket socket=new Socket(“127.0.0.1”,8080);
通过inputstream读取数据,获取服务器发出的数据
OutputStream os=socket.getOutputStream();
通过OutputStream发送数据
进行TCP协议Socket数据传输
- 一般步骤
1.打开连接
2.取得outputstream和inputstream
3.关闭连接
package com.example.sgcchj;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
public class ScoketUtils {
private static Socket socket;
private static InputStream is;
private static InputStreamReader isr;
private static BufferedReader br;
private static OutputStream outputStream;
public static void openlink(){
try {
// 创建Socket对象 & 指定服务端的IP 及 端口号
socket = new Socket("192.168.0.102", 10086);
// 判断客户端和服务器是否连接成功
System.out.println(socket.isConnected()+"是否连接成功");
} catch (IOException e) {
e.printStackTrace();
}
}
public static void readlink(){
try {
is = socket.getInputStream();
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
String response = br.readLine();
System.out.println(response+"这是个啥");
} catch (IOException e) {
e.printStackTrace();
}
}
public static void writelink(String data){
try {
outputStream = socket.getOutputStream();
byte[] b=data.getBytes("utf-8");
outputStream.write(b);
outputStream.flush();
} catch (IOException e) {
}
}
public static void closelink(){
try {
if(outputStream!=null){
outputStream.close();
}
if(br!=null){
br.close();
}
if(socket!=null){
socket.close();
System.out.println(socket.isConnected());
}
} catch (IOException e) {
}
}
}
Android HTTP通信
- 什么是HTTP协议
HTTP协议即超文本传送协议(Hypertext Transfer Protocol ),是Web联网的基础,也是手机联网常用的协议之一,HTTP协议是建立在TCP协议之上的一种应用。
HTTP连接最显著的特点是客户端发送的每次请求都需要服务器回送响应,在请求结束后,会主动释放连接。从建立连接到关闭连接的过程称为“一次连接”。
HTTP是一个属于应用层的面向对象的协议,Http协议基于传输层的TCP协议,主要解决如何包装数据 - Android开发调用
Android中提供的HttpURLConnection和HttpClient(已过时,不在说)和开源的okhttp3接口可以用来开发HTTP程序。
1. HttpURLConnection接口
首先需要明确的是,Http通信中的POST和GET请求方式的不同。GET可以获得静态页面,也可以把参数放在URL字符串后面,传递给服务器。而POST方法的参数是放在Http请求中。因此,在编程之前,应当首先明确使用的请求方法,然后再根据所使用的方式选择相应的编程方式。
HttpURLConnection是继承于URLConnection类,二者都是抽象类。其对象主要通过URL的openConnection方法获得。创建方法如下代码所示:
URL url = new URL("http://127.0.0.1/post.jsp");
HttpURLConnection urlConn=(HttpURLConnection)url.openConnection();
通过以下方法可以对请求的属性进行一些设置,如下所示
//设置输入和输出流
urlConn.setDoOutput(true);
urlConn.setDoInput(true);
//设置请求方式为POST
urlConn.setRequestMethod("POST");
//POST请求不能使用缓存
urlConn.setUseCaches(false);
//关闭连接
urlConn.disConnection();
Manifest文件中权限的设定:
Xml代码
<uses-permission android:name="android.permission.INTERNET" />
HttpURLConnection默认使用GET方式,例如下面代码所示:
//以Get方式上传参数
public class Activity1 extends Activity
{
private final String DEBUG_TAG = "Activity1";
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.http);
TextView mTextView = (TextView)this.findViewById(R.id.tv_http);
//http地址"?id=1"是我们上传的参数
String httpUrl = "http://127.0.01:8080/index.jsp?id=1";
//获得的数据
String resultData = "";
URL url = null;
try
{
//构造一个URL对象
url = new URL(httpUrl);
}
catch (MalformedURLException e)
{
Log.e(DEBUG_TAG, "完犊子");
}
if (url != null)
{
try
{
// 使用HttpURLConnection打开连接
HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
//得到读取的内容(流)
InputStreamReader in = new InputStreamReader(urlConn.getInputStream());
// 为输出创建BufferedReader
BufferedReader buffer = new BufferedReader(in);
String Line = null;
//使用循环来读取获得的数据
while (((Line = buffer.readLine()) != null))
{
//我们在每一行后面加上一个"\n"来换行
resultData += Line + "\n";
}
//关闭InputStreamReader
in.close();
//关闭http连接
urlConn.disconnect();
//设置显示取得的内容
if ( resultData != null )
{
mTextView.setText(resultData);
}
else
{
mTextView.setText("读取的内容为NULL");
}
}
catch (IOException e)
{
Log.e(DEBUG_TAG, "扯犊子");
}
}
else
{
Log.e(DEBUG_TAG, "Url NULL");
}
}
如果需要使用POST方式,则需要setRequestMethod设置。代码如下:
//以post方式上传参数
public class Activity2extends Activity
{
private final String DEBUG_TAG = "Activity2";
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.http);
TextView mTextView = (TextView)this.findViewById(R.id.TextView_HTTP);
//http地址"?id=1"是我们上传的参数
String httpUrl = "http://192.168.1.110:8080/post.jsp";
//获得的数据
String resultData = "";
URL url = null;
try
{
//构造一个URL对象
url = new URL(httpUrl);
}
catch (MalformedURLException e)
{
Log.e(DEBUG_TAG, "MalformedURLException");
}
if (url != null)
{
try
{
// 使用HttpURLConnection打开连接
HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
//因为这个是post请求,设立需要设置为true
urlConn.setDoOutput(true);
urlConn.setDoInput(true);
// 设置以POST方式
urlConn.setRequestMethod("POST");
// Post 请求不能使用缓存
urlConn.setUseCaches(false);
urlConn.setInstanceFollowRedirects(true);
// 配置本次连接的Content-type,配置为application/x-www-form-urlencoded的
urlConn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
// 连接,从postUrl.openConnection()至此的配置必须要在connect之前完成,
// 要注意的是connection.getOutputStream会隐含的进行connect。
urlConn.connect();
//DataOutputStream流
DataOutputStream out = new DataOutputStream(urlConn.getOutputStream());
//要上传的参数
String content = "par=" + URLEncoder.encode("ABCDEFG", "gb2312");
//将要上传的内容写入流中
out.writeBytes(content);
//刷新、关闭
out.flush();
out.close();
//获取数据
BufferedReader reader = new BufferedReader(new InputStreamReader(urlConn.getInputStream()));
String inputLine = null;
//使用循环来读取获得的数据
while (((inputLine = reader.readLine()) != null))
{
//我们在每一行后面加上一个"\n"来换行
resultData += inputLine + "\n";
}
reader.close();
//关闭http连接
urlConn.disconnect();
//设置显示取得的内容
if ( resultData != null )
{
mTextView.setText(resultData);
}
else
{
mTextView.setText("读取的内容为NULL");
}
}
catch (IOException e)
{
Log.e(DEBUG_TAG, "IOException");
}
}
else
{
Log.e(DEBUG_TAG, "Url NULL");
}
}
}
2.okhttp3接口
导入:compile 'com.squareup.okhttp3:okhttp:3.9.0'
Get请求
String url = "https://127.0.0.1/";
OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder()
.url(url)
.build();
Call call = okHttpClient.newCall(request);
try {
Response response = call.execute();
System.out.println(response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
传参:
Request request = new Request.Builder()
.url(url)
.header(key, value)
.build();
Post请求
String url = "https://127.0.0.1";
OkHttpClient okHttpClient = new OkHttpClient();
RequestBody body = new FormBody.Builder()
.add(key, value)
.build();
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
Call call = okHttpClient.newCall(request);
try {
Response response = call.execute();
System.out.println(response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
post请求创建request和get是一样的,post请求需要提交一个表单,就是RequestBody。
RequestBody body = new FormBody.Builder()
.add(key, value)
.build();