Android网络应用之使用Scoket的Android客户端与TCP服务器的简单交互

在介绍代码之前先来背一下书吧。

  TCP/IP协议:Transmission Control Protocol/Internet Protocol的简写,中译名为传输控制协议/因特网互联协议,又名网络通讯协议,是Internet最基本的协议、Internet国际互联网络的基础,由网络层的IP协议和传输层的TCP协议组成。TCP/IP 定义了电子设备如何连入因特网,以及数据如何在它们之间传输的标准。协议采用了4层的层级结构,每一层都呼叫它的下一层所提供的协议来完成自己的需求。通俗而言:TCP负责发现传输的问题,一有问题就发出信号,要求重新传输,直到所有数据安全正确地传输到目的地。而IP是给因特网的每一台联网设备规定一个地址。

  看完以后还是觉得有点懵比……简单的说就是TCP/IP通信协议是一种可靠的(老哥,稳!)网络协议,它在通信的两端各建立一个Socket,从而在通信两段之间形成网络虚拟链路。,一旦链路建立了,那么两端的程序就可以通过虚拟链路进行通信了。在两个通信实体没有建立虚拟链路之前,必须要有一个通信实体先做出“主动姿态”,主动接收来自其他通信实体的连接请求。这个好理解啊!就好比恋爱就是虚拟链路嘛,只有男生或女生肯接受来自对方的表白我们才有戏啊对吧?那么才有后面的花前月下哈咳咳,扯远了,正经点!

具体分两部分来讲解吧。

第一部分:服务器端:

使用ServerSocket创建TCP服务器端:

  Java接收其他通信实体连接请求的类是ServerSocket,没有连接就一直等待。它包含一个来自客户端连接请求的方法Socket accept():有链接就返回一个与连接客户端对应的socket,否则就一直处于等待状态,线程也被阻塞。

为了创建ServerSocket对象,类提供了几个构造器:

  1. ServerSocket(intport):用指定端口来创建ServerSocket,有效值0~65535
  2. ServerSocket(intport,int backlog):增加一个用了改变队列长度的参数backlog
  3. ServerSocket(intport,int backlog,IntAddress localAddr):在存在多个IP的情况下允许通过localAddr绑定到指定。                                                             用完后就用close()方法关闭。通常会接收多个请求,所以要不断调用accept方法。

ServerSocketss = new ServerSocket(30000);
//30000为端口号避免冲突选1024以上。
While(true){//不断接收请求
Socket s= ss.accetp();
…..//可以恋爱,噢,不! 通信了
}

服务器用的是Eclipse,其实没什么要求,eclipse,myeclipse都行的,因为JDK本身就包含了TCP的网络通信API所以用Socket不需要其他服务器支持就可以了。

这里给出服务器端的代码:

public class SimpleServer
{
	public static void main(String[] args)
		throws IOException
	{
		// 创建一个ServerSocket,用于监听客户端Socket的连接请求
		ServerSocket ss = new ServerSocket(23000); 
		// 采用循环不断接受来自客户端的请求
		while (true)
		{
			// 每当接受到客户端Socket的请求,服务器端也对应产生一个Socket
			Socket s = ss.accept();
			OutputStream os = s.getOutputStream();
			os.write(" 来追我呀!如果你追到我,我就跟你一起走可持续发展的中国特色社会主义道路!!!\n"
				.getBytes("utf-8"));
			// 关闭输出流,关闭Socket
			os.close();
			s.close();
		}
	}
}

都说了很简单的了吧!!!

第二部分:客户端(更简单):

使用Socket进行通信

  客户端通常可以用Socket构造器来指定连接到指定服务器,通常提供两个构造器:

  1. Socket(IntAddress/StringremoteAddress, int port):创建连接到指定远程主机远程端口的Socket,该构造器没有指定本地地址,本地端口,默认使用本地主机的默认IP地址,默认使用系统动态分配的端口。
  2. Socket(IntAddress/StringremoteAddress, int port,InetAddress localAddr,int localPort):创建连接到指定远程主机,端口的Socket,并指定本地IP地址,适用于本地主机有多个IP地址的情况。

//创建连接到192.168.1.88,30000端口的Socket
Socket s = newSocket(“192.168.1.88”,30000);
//下面可以使用Socket进行通信了

其实在客户端,服务器端产生了对应的Socket之后,这时候就不用再分服务器,客户端了,而是通过各自的Socket进行通信,同时Socket进行通信。Socket提供了如下两个方法来获取输入流跟输出流:

  • InputStream  getInputStream():返回该Socket对象对应的输入流,让程序通过该输入流从Socket中取出数据。
  • OutputStream getOutputStream():返回该Socket对象对应的输出流,让程序通过该输出流向Socket中输出数据。

看到这两个方法返回的InputStream和OutputStream,读者应该可以明白Java在设计IO体系上的苦心了:不管底层的IO流是怎样的节点流,文件流也好,网络Socket产生的流也好,程序都可以将其包装成处理流,从而提供更多方便的处理。


我用的是Android Studio的来编写客户端代码,以下是代码:

public class MainActivity extends Activity
{
   EditText show;
   @Override
   public void onCreate(Bundle savedInstanceState)
   {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);
      show = (EditText) findViewById(R.id.show);
      new Thread()
      {
         @Override
         public void run()
         {
            try
            {
               // 建立连接到远程服务器的Socket
               Socket socket = new Socket("192.168.43.146", 23000);  // ①
               // 将Socket对应的输入流包装成BufferedReader
               BufferedReader br = new BufferedReader(
                     new InputStreamReader(socket.getInputStream()));
               // 进行普通I/O操作
               String line = br.readLine();
               show.setText("来自服务器的数据:" + line);
               // 关闭输入流、socket
               br.close();
               socket.close();
            }
            catch (IOException e)
            {
               e.printStackTrace();
            }
         }
      }.start();
   }
}

别忘了因为要联网(连接服务器嘛)所以要在配置文件中加入对应的权限:




通信成功截图:

Android网络应用之使用Scoket的Android客户端与TCP服务器的简单交互_第1张图片

别看现在这么简单后面可就难了。不过学习嘛,要循序渐进,慢慢深入。



你可能感兴趣的:(Android网络应用)