对于网络方面的知识在这里不作详细的介绍,读者可以参考《TCP/IP详解 I II III》等网络书籍。
下面简单的谈下网络通信协议和网络通信协议接口。
网络通信协议:计算机网络中实现通信必须有一些约定即通信协议,对速率,传输代码,代码结构,传输控制步骤,出错控制等制定标准。
网络通信接口:为了使两个结点之间能进行对话,必须在它们之间建立通信工具(即接口),使得彼此之间能进行信息交换。接口包括两部分:
java中提供了两种常见的网络协议支持,TCP/UDP,关于这这两种协议,懂网络基础知识的朋友都知道这两种协议属于OSI(TCP/IP)中运输层的协议,在TCP/IP中,把OSI简化为四层,其中运输层与应用层直接交互。
下面简单的介绍TCP/UDP协议:
TCP:是专门设计用于在不可靠的因特网上提供可靠的,端到端的字节流通信协议,它是一种面向连接的协议。TCP连接是字节流而非报文流。
UDP:向应用程序提供了了一种发送封装的原始IP数据报(包,分组)的方法,并且发送时无需建立连接,是一种不可靠的连接,但是效率高,广泛的运用在视频传输,语音通话等通信中。
而Socket 编程是使用最广泛的网络概念套接字使用TCP提供了两台计算机之间的通信机制。 客户端程序创建一个套接字,并尝试连接服务器的套接字。当连接建立时,服务器会创建一个Socket对象。客户端和服务器现在可以通过对Socket对象的写入和读取来进行进行通信。java.net.Socket类代表一个套接字,并java.net.ServerSocket类为服务器程序提供了一种来监听客户端,并与他们建立连接的机制。
以下步骤在两台计算机之间使用套接字建立TCP连接时会出现:
服务器实例化一个ServerSocket对象,表示通过服务器上的端口通信,该对象很像监听器,监听客户端是否有用户来连接。服务器调用 ServerSocket类 的accept()方法,该方法将一直等待,直到客户端连接到服务器上给定的端口。服务器正在等待时,一个客户端实例化一个Socket对象,指定服务器名称和端口号来请求连接。Socket类的构造函数试图将客户端连接到指定的服务器和端口号。如果通信被建立,则在客户端创建一个Socket对象能够与服务器进行通信。在服务器端,accept()方法返回服务器上一个新的socket引用,该socket连接到客户端的socket。连接建立后,通过使用I/O流在进行通信。每一个socket都有一个输出流和一个输入流。客户端的输出流连接到服务器端的输入流,而客户端的输入流连接到服务器端的输出流。TCP是一个双向的通信协议,因此数据可以通过两个数据流在同一时间发送.以下是一些类提供的一套完整的有用的方法来实现sockets。具体方法详见java.net包中定义的两个类Scoket和ServerScoket。(http://docs.oracle.com/javase/8/docs/api/index.html)
以上client与server通信过程可以简单的用下面的示意图来表示:
下面客户端与服务器端进行简单的
TCP协议通信:
-
public class TCPServer {
-
public static void main(String[] args){
-
-
try {
-
@SuppressWarnings("resource")
-
ServerSocket server = new ServerSocket(11111);
-
Socket ser = server.accept();
-
DataInputStream in = new DataInputStream(ser.getInputStream());
-
OutputStream ou = ser.getOutputStream();
-
DataOutputStream out = new DataOutputStream(ou);
-
out.writeUTF("hi!Client!");
-
System.out.println(in.readUTF());
-
out.flush();
-
out.close();
-
} catch (IOException e) {
-
// TODO 自动生成的 catch 块
-
e.printStackTrace();
-
}
-
}
-
}
-
-
public class TCPClient {
-
public static void main(String[] args){
-
-
try {
-
@SuppressWarnings("resource")
-
Socket client = new Socket("127.0.0.1",11111);
-
OutputStream out = client.getOutputStream();
-
DataOutputStream data = new DataOutputStream(out);
-
DataInputStream inn = new DataInputStream(client.getInputStream());
-
System.out.println(inn.readUTF());
-
data.writeUTF("hi!server!");
-
data.flush();
-
data.close();
-
inn.close();
client.close();
-
} catch (UnknownHostException e) {
-
e.printStackTrace();
-
} catch (IOException e) {
-
e.printStackTrace();
-
}
-
}
-
}
从上面看出,client端发出与ip为127.0.0.1,端口号为11111的服务器进行socket通信,并且对服务器端发出问候,此时服务器端的accept()正在监视11111端口,如果有socket请求,则马上建立连接,并把从客户端发来的信息打印出来,此时服务器端也向客户端发出问候,并打印结果:
上面只是简单的一对一进行通信,可以多个客户端对一个服务器端发出通信请求, 对上面的代码进行修改就可以简单实现,再添加一个客户端类TCPClient1,代码如下:
-
public class TCPServer {
-
public static void main(String[] args){
-
-
try {
-
@SuppressWarnings("resource")
-
ServerSocket server = new ServerSocket(11111);
-
while(true){
-
Socket ser = server.accept();
-
DataInputStream in = new DataInputStream(ser.getInputStream());
-
OutputStream ou = ser.getOutputStream();
-
DataOutputStream out = new DataOutputStream(ou);
-
out.writeUTF("hi!Client!");
-
System.out.println(in.readUTF());
-
out.flush();
-
out.close();
-
}
-
-
} catch (IOException e) {
-
// TODO 自动生成的 catch 块
-
e.printStackTrace();
-
}
-
}
-
}
-
-
public class TCPClient {
-
public static void main(String[] args){
-
-
try {
-
@SuppressWarnings("resource")
-
Socket client = new Socket("127.0.0.1",11111);
-
OutputStream out = client.getOutputStream();
-
DataOutputStream data = new DataOutputStream(out);
-
DataInputStream inn = new DataInputStream(client.getInputStream());
-
System.out.println(inn.readUTF());
-
data.writeUTF("hi!server!");
-
data.flush();
-
data.close();
-
inn.close();
-
client.close();
-
} catch (UnknownHostException e) {
-
// TODO 自动生成的 catch 块
-
e.printStackTrace();
-
} catch (IOException e) {
-
// TODO 自动生成的 catch 块
-
e.printStackTrace();
-
}
-
}
-
}
-
-
-
public class TCPClient1 {
-
-
public static void main(String[] args){
-
-
try {
-
@SuppressWarnings("resource")
-
Socket client = new Socket("127.0.0.1",11111);
-
OutputStream out = client.getOutputStream();
-
DataOutputStream data = new DataOutputStream(out);
-
DataInputStream inn = new DataInputStream(client.getInputStream());
-
System.out.println(inn.readUTF());
-
data.writeUTF("hi!server!");
-
data.flush();
-
data.close();
-
inn.close();
-
client.close();
-
} catch (UnknownHostException e) {
-
// TODO 自动生成的 catch 块
-
e.printStackTrace();
-
} catch (IOException e) {
-
// TODO 自动生成的 catch 块
-
e.printStackTrace();
-
}
-
}
-
}
下面谈谈基于UDP协议的网络通信,由于UDP通信是发送的IP数据报,无需建立连接,是一种不可靠的连接,这和TCP通信有很大的区别。
-
public class UDPServer {
-
public static void main(String[] args){
-
-
byte b[] = new byte[1000];
-
DatagramPacket dp = new DatagramPacket(b, b.length);
-
ByteArrayOutputStream by = new ByteArrayOutputStream();
-
DataOutputStream byt = new DataOutputStream(by);
-
-
try {
-
DatagramSocket ds = new DatagramSocket(111);
-
ds.receive(dp);
-
ByteArrayInputStream bais = new ByteArrayInputStream(b);
-
DataInputStream dis = new DataInputStream(bais);
-
System.out.println(dis.readUTF());
-
byt.writeUTF("hi!Client!");
-
byte c[] = by.toByteArray();
-
DatagramPacket dpp = new DatagramPacket(c, c.length,new InetSocketAddress("127.0.0.1", 1111));
-
DatagramSocket dss = new DatagramSocket();
-
dss.send(dpp);
-
} catch (SocketException e1) {
-
// TODO 自动生成的 catch 块
-
e1.printStackTrace();
-
} catch (IOException e) {
-
// TODO 自动生成的 catch 块
-
e.printStackTrace();
-
}
-
}
-
}
-
public class UDPClient {
-
public static void main(String[] args){
-
-
-
ByteArrayOutputStream w = new ByteArrayOutputStream();
-
DataOutputStream ou = new DataOutputStream(w);
-
byte d[] = new byte[1000];
-
DatagramPacket dpp = new DatagramPacket(d, d.length);
-
-
-
try {
-
-
DatagramSocket dss = new DatagramSocket(1111);
-
ou.writeUTF("hi,Server!");
-
byte a[] = w.toByteArray();
-
DatagramPacket dp = new DatagramPacket(a, a.length,new InetSocketAddress("127.0.0.1", 111));
-
DatagramSocket ds = new DatagramSocket();
-
ds.send(dp);
-
dss.receive(dpp);
-
ByteArrayInputStream bais = new ByteArrayInputStream(d);
-
DataInputStream dis = new DataInputStream(bais);
-
System.out.println(dis.readUTF());
-
} catch (IOException e) {
-
// TODO 自动生成的 catch 块
-
e.printStackTrace();
-
}
-
}
-
}
以上同样是server与Client端相互通信,和TCP协议通信有很大的区别,其中有很多的细节还需要注意。虽然UDP不需要建立连接,但是在网络传送中,需要告诉它目的主机IP,以及应用程序端口号,然后经过层层的封装,然后由底层物理链路传送比特流。
以上作为个人学习总结,有很多知识没有总结到,比如URL,URI类。上文如有不当或错误之处,请读者指正!谢谢!
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/29876893/viewspace-1830004/
,如需转载,请注明出处,否则将追究法律责任。