在介绍代码之前先来背一下书吧。
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对象,类提供了几个构造器:
ServerSocket(int port):用指定端口来创建ServerSocket,有效值0~65535
ServerSocket(intport,int backlog):增加一个用了改变队列长度的参数backlog
ServerSocket(intport,intbacklog,IntAddresslocalAddr):在存在多个IP的情况下允许通过localAddr绑定到指定IP
用完后就用close()方法关闭。通常会接收多个请求,所以要不断调用accept方法。
ServerSocketss = new ServerSocket(30000);//30000为端口号避免冲突选1024以上。
While(true){//不断接收请求
Socket s = ss.accetp();
…..//可以恋爱,噢,不! 通信了
}
服务器用的是Eclipse,其实没什么要求,eclipse,myeclipse都行的,因为JDK本身就包含了TCP的网络通信API所以用Socket不需要其他服务器支持就可以了。
这里给出服务器端的代码:
publicclassSimpleServer
{
publicstaticvoid main(String[] args)
throwsIOException
{
// 创建一个ServerSocket,用于监听客户端Socket的连接请求
ServerSocketss = newServerSocket(23000);
// 采用循环不断接受来自客户端的请求
while (true)
{
// 每当接受到客户端Socket的请求,服务器端也对应产生一个Socket
Socket s = ss.accept();
OutputStreamos = s.getOutputStream();
os.write(" 来追我呀!如果你追到我,我就跟你一起走可持续发展的中国特色社会主义道路!!!\\n"
.getBytes("utf-8"));
// 关闭输出流,关闭Socket
os.close();
s.close();
}
}
}
都说了很简单的了吧!!!
第二部分:客户端(更简单):
使用Socket进行通信
客户端通常可以用Socket构造器来指定连接到指定服务器,通常提供两个构造器:
Socket(IntAddress/String remoteAddress, int port):创建连接到指定远程主机远程端口的Socket,该构造器没有指定本地地址,本地端口,默认使用本地主机的默认IP地址,默认使用系统动态分配的端口。
Socket(IntAddress/String remoteAddress, intport,InetAddresslocalAddr,intlocalPort):创建连接到指定远程主机,端口的Socket,并指定本地IP地址,适用于本地主机有多个IP地址的情况。
//创建连接到192.168.1.88,30000端口的Socket
Socket s = new Socket(“192.168.1.88”,30000);
//下面可以使用Socket进行通信了
其实在客户端,服务器端产生了对应的Socket之后,这时候就不用再分服务器,客户端了,而是通过各自的Socket进行通信,同时Socket进行通信。Socket提供了如下两个方法来获取输入流跟输出流:
●InputStreamgetInputStream():返回该Socket对象对应的输入流,让程序通过该输入流从Socket中取出数据。
●OutputStreamgetOutputStream():返回该Socket对象对应的输出流,让程序通过该输出流向Socket中输出数据。
看到这两个方法返回的InputStream和OutputStream,读者应该可以明白Java在设计IO体系上的苦心了:不管底层的IO流是怎样的节点流,文件流也好,网络Socket产生的流也好,程序都可以将其包装成处理流,从而提供更多方便的处理。
我用的是Android Studio的来编写客户端代码,以下是代码:
public class MainActivityextends Activity
{
EditTextshow;
@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
Socketsocket = new Socket("192.168.43.146", 23000); // ①
// 将Socket对应的输入流包装成BufferedReader
BufferedReaderbr = 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();
}
}
别忘了因为要联网(连接服务器嘛)所以要在配置文件中加入对应的权限:
通信成功截图:
别看现在这么简单后面可就难了。不过学习嘛,要循序渐进,慢慢深入。下载本文