TCP是一个面向连接的协议,所以在连接双方发送数据之前,都需要首先建立一条连接。这和前面讲到的协议完全不同。前面讲的所有协议都只是发送数据而已,大多数都不关心发送的数据是不是送到,UDP尤其明显,从编程的角度来说,UDP编程也要简单的多----UDP都不用考虑数据分片。
书中用telnet登陆退出来解释TCP协议连接的建立和中止的过程,可以看到,TCP连接的建立可以简单的称为三次握手,而连接的中止则可以叫做四次握手。
下面将通过代码简单介绍一下其实现过程:
1.首先在AndroidStudio中建立一个项目,将它作为服务器。
我们先建立一个服务,即新建一个类继承自Service:
package com.android.lanou.tcpservice.service;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;
import com.android.lanou.tcpservice.TCPLogic;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
/**
* Created by xalo on 16/8/24.
*/
public class TCPService extends Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
new Thread(new Runnable() {
@Override
public void run() {
Log.d("---run---", "启动了");
try {
ServerSocket ss = new ServerSocket(50000);
//这条数据是阻塞式的
Socket socket;
while((socket = ss.accept())!= null) {
new Thread(new TCPLogic(socket)).start();
}
Log.d("---ss---", socket.getInetAddress().toString());
} catch (IOException e) {
e.printStackTrace();
}
Log.d("---end---", "结束了");
}
}).start();
}
}
然后再新建另一个class:
package com.android.lanou.tcpservice;
import android.util.Log;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;
/**
* Created by xalo on 16/8/24.
*/
public class TCPLogic implements Runnable {
Socket socket;
public TCPLogic(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
InputStream is = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String str;
while ((str = br.readLine()) != null) {
Log.d("---str---", str);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
在MainActivity中我们开始启动该服务:
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import com.android.lanou.tcpservice.service.TCPService;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
private void init() {
Intent intent = new Intent(this, TCPService.class);
this.startService(intent);
}
}
这样我们的服务已经建立好了,接下来新建另一个项目,作为一个连接者。在该项目中我们只需一个Activity即可实现其功能,作为一个连接者,我们的目的是与服务器进行连接,获取或者向服务器发送数据;那么先在xml文件中建立一个Button,作为发送器,每次点击希望都能实现与服务器的交流,使服务器收到我们发送的这条消息。
package com.android.lanou.tcpclient;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
public class MainActivity extends AppCompatActivity {
Socket socket;
PrintWriter bw;
Button btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
new Thread(new Runnable() {
@Override
public void run() {
try {
connect();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
private void init(){
btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
sendMsg("你好");
}
});
}
private void connect() throws IOException {
InetAddress address = InetAddress.getByName("localhost");
socket = new Socket(address, 50000);
OutputStream out = socket.getOutputStream();
bw = new PrintWriter(out);
}
private void sendMsg(String msg) {
bw.println(msg);
bw.flush();
}
}
这样,每次点击按钮服务器就会收到我们发送的消息了。