本文主要讲的是如何用Socket实现TCP和UDP基础上的服务器端和客户端通信。在代码上的通信流程和一些细节以及两者在代码上的区别和原因。
目录
一、Socket
首先明确,Socket是一个本地的标识,只和本端有关系,其它端是不知道的。
同时Socket标识着本地ip的某个端口和其它端ip的某个端口的一个连接关系,因此这个socket里面有自己的ip和端口。
它就像本端的某一扇门一样,一扇标识的门,我们需要将我们的想要发送的数据从这扇门发出去,同时向本机端口发送的数据也需要通过这扇门收进来。这个是socket最主要的作用,就是收和发的作用,数据发出和接收都需要通过这个socket。当我们需要发出相关数据时,需要调用这个socket发出的相关方法。当我们需要接收数据时,我们也是需要调用这个socket的相关方法来接收的。
并且注意了socket标识的作用,就是当我们发消息给对方的时候,对方知道是我们发的,就是因为我们是通过这个socket发的,因为socket上面有端口号和ip地址。接也是同样道理的,网络这么大,怎么知道是哪个ip地址哪个端口来接呢?就是因为有socket在这里,当有消息发过来的时候,socket可以和发过来的消息对应上,然后通过对应的上的这个socket来接收消息。<---这里主要是udp的,但其实tcp也是一样的,只是没有特别显式而已。
简写步骤
注意这里都是一次性的操作,也就是一个客户端发过去然后收回来,没有实现同一个客户端向服务器多次发送的操作。tcp代码在SocketTest003
二、TCP方式通信
服务器端
● 创建欢迎套接字socket
1、创建欢迎套接字socket,其中需要传入ip地址和端口号,也就是握手的操作。注意这个socket只是一个本地的标识,是等着客户端来连接的。
● 创建专属套接字socket
2、需要在欢迎套接字的基础调用accept方法,为发送端和自己创建一个专门的套接字socket,不需要传入ip地址和端口号了。然后利用这个专属socket来进行读取和发送的操作。
● 读取数据流
3、需要调用socket的getInputStream方法,然后就可以调用read方法就可以读取到客户端发送过来的数据了。这里我们使用了缓冲流BufferedReader来读取。然后记得最后需要关闭这个缓冲流,但是不能直接close,而是要调用shutdownInput()方法,这样只会关闭这个读的部分而不会直接关闭socket,而close会。然后需要注意,read的时候如果没有数据发过来,是会阻塞的。
● 发送数据流
4、需要调用socket的getOutputStream方法,然后调用write方法就可以往外面写出,数据就写出去了,对方如果有调用read方法就接收的到了。这里我们使用了缓冲流BufferedWriter来写出。然后切记要调用一下flush方法将缓存里面的东西刷出去。最后记得需要关闭这个流,但是也不能直接close,而是要调用shutdownOutput()方法,这样只会关闭输出的部分而不会关闭socket。
● 关闭socket
直接调用socket的close方法将它们关闭。