Android中基于TCP协议的网络通信之使用Socket进行通信

TCP协议被称为一种端到端的协议。这是因为它为两台计算机的连接起到了重要作用:当一台计算机需要与另一台计算机进行接连时,TCP协议会他们之间建立一个连接:用于发送和接收数据的虚拟链路。

TCP协议负责收集这些信息包,并将其按适当的顺序放好传送,在接收端收到后再将其正确地还原。TCP协议确保了数据包在传送中准确无误。TCP协议使用重发机制:当一个通信实体发送一个消息给另一个通信实体后,需要收到另一个通信实体的确认信息,如果没有收到另一个通信实体的确认信息,则会重发刚才发送的消息。可以通过下面的图例来简单了解TCP协议控制两个通信实体互相通信的过程:


Java中能接收其他通信实体连接请求的类是ServerSocket,ServerSocket对象用来监听来自客户端的Socket连接,如果没有连接,它将一直处于等待状态。

根据上面的示意图,可以看出我们至少需要两个计算机设备才能进行通信。一个是服务器端,一个客户端。在这里可能有人会说:那两个人聊QQ、微信的时候两个都是客户端啊。不错,的确两个都是客户端。但是,要知道,这两个客户端都要和腾讯的服务器连接才能通信。好了,下面我们就来用代码来做一个综述。

首先是服务器端(Java程序,运行于PC):

public class SimpleServer {

	public static void main(String[] args) throws IOException{
		ServerSocket ss = new ServerSocket(30000);
		while (true) {
			Socket s = ss.accept();
			OutputStream os = s.getOutputStream();
			os.write(("我是william的忠实服务器!" + Calendar.getInstance().getTimeInMillis()).getBytes("utf-8"));
			os.close();
			s.close();
		}
	}
}
这里我用的端口号是30000,一般来说我们推荐使用1024以上的端口号,主要是为了避免与其他的应用程序的通用端口发生冲突。

这里我们用了一个死循环来监听来自客户端的连接信息。这里我们是把当前毫秒时间传给了Socket的outputStream。这里一点需要注意,那就是我用了一个.getBytes("utf-8")。这是因为,我们的服务器端是运行在PC上,一般是Windows主机,当直接使用PrintStream输出字符串时默认使用系统平台的字符串(GBK)编码,但客户端都是Android程序,运行于Linux平台,因为客户端读取网络数据时默认使用UTF-8字符集进行解码,这样就会造成乱码。

----------------------------------------------------------------------------------------------------------------------------------------------------------

下面是客户端程序(Android程序,运行于Android机):

Handler handler = new Handler(){
		public void handleMessage(android.os.Message msg) {
			if (msg.what == 123) {
				try {
					Socket socket = new Socket("192.168.1.105", 30000);
					BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
					String line = reader.readLine();
					
					TextView showTextView = (TextView) findViewById(R.id.activity_simple_client_textview);
					showTextView.setText("来自服务器的数据:" + line);
					reader.close();
					socket.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		};
	};
这里只提供了在Handler线程中的关键代码,因为在UI线程的部分非常简单,这里不给出代码,完整代码后面会有接连源码下载。
在客户端我们使用了IP为192.168.1.105的主机,因为笔者的PC就是这个IP。如果你的电脑你不知道怎么查看IP或是你的IP地址是设置为自动获取IP地址,那么可以使用下图的方法(在开始菜单下输入cmd进入命令提示符窗口):



进入cmd的方法:



另外如果你需要修改你的服务器端程序,并且要运行修改后的程序,你可能会遇到这样的一种情况:


遇到这种情况,不是你的程序修改的时候有问题。而是因为这个时候,你的服务器端程序里写了一个死循环,这个死循环会一直在运行。我们可以通过任务管理器查看到这个进程还在运行着,如下:


我们只在kill掉这个进程,然后再运行服务器程序,这样就可以了。

运行程序,如下结果:



本博客参考资料:《疯狂Android讲义》

这里是我的程序源码(服务器端和客户端):点击下载源码



原文地址:https://www.cnblogs.com/fengju/p/6336148.html