Java网络编程基础

网络编程

网络编程模型主要由C/S(Client/Server)B/S(Browser/Server)两种结构。而网络编程中有两个主要的问题,一是如何定位网络上的主机,二是如何数据传输时如何做到可靠与高效。为了解决这两个问题,相互通信的计算机就必须遵循一定的网络协议,较为广泛使用的是TCP/IPUDP/IP

Java–使用ServerSocketSocket开发TCP/IP网络程序

Java提供了SocketServerSocket两个类,分别用来表示双向连接的Client和Server。
服务器端创建Socket并监听客户端的连接。

ServerSocket myServerSocket = new ServerSocket(port);
Socket clientSocket = myServerSocket.accept();

客户端想要通过建立Socket连接到服务器就需要知道服务器网络地址和端口号,这里的serverPort相当于上面的port。

Socket mySocket = new Socket(serverAddress, serverPort);

此时Server和Client已经连接起来,双方进行通信还需要I/O流进行读写操作。
服务器端创建I/O流对象。

ObjectOutputStream outputToClient = new ObjectOutputStream(clientSocket.getOutputStream());
ObjectInputStream inputFromClient = new ObjectInputStream(clientSocket.getInputStream());

客户端创建I/O流对象。

ObjectOutputStream outputToServer = new ObjectOutputStream(mySocket.getOutputStream());
ObjectInputStream inputFromServer = new ObjectInputStream(mySocket.getInputStream());

之后双方就可以进行正常地通信了。

这里假设有一个User类,Client想向Server传了一个User对象,那就应该在Client的输出流中写入这个User对象,并对输出流进行刷新,是Server马上收到User对象。

outputToServer.writeObject(new User(username, password));
outputToServer.flush();

Server从输入流接收到Client传来的User对象。

User user = (User)inputFromClient.readObject();

双方结束通信后注意要关闭Socket,且在此之前要将Socket连接的输入输出流关闭。

Java–使用DatagramSocketDatagramPacket开发UDP/IP网络程序

Server和Client双方想要进行通信时,需要创建DatagramSocket对象,通过DatagramSocket对象的方法send()和receive()就可以实现发送和接收数据报。而这两个方法需要一个数据报传输的载体,DatagramPacket就是这个载体。

那首先,如何使Client如何知道Server的地址和端口?Server又是如何知道是谁发来的数据报呢?

我们先看一下DatagramSocket的构造:

DatagramSocket():创建一个DatagramSocket对象,并将该对象绑定到本机默认IP地址、本机所有可用端口中随机选择的某个端口。

DatagramSocket(int prot):创建一个DatagramSocket对象,并将该对象绑定到本机默认IP地址、指定端口。

DatagramSocket(int port, InetAddress address):创建一个DatagramSocket对象,并将该对象绑定到指定IP地址、指定端口。

所以可以在Server创建一个DatagramSocket对象,通过getLocalPort()方法获取端口号,如果是本机作为服务器,则地址可以用InetAddress.getLocalHost()来获取。Client通过Server的地址和端口号向Server发送数据报时,Server便可以得知Client的地址和端口。

下面以Client向Server获取时间作为例子。

首先,在Server创建DatagramSocket对象,并创建一个DatagramPacket对象用来接收来自Client的数据报。

DatagramSocket datagramSocket = new DatagramSocket(port); 
byte[] msg = new byte[10];
DatagramPacket inDataPacket = new DatagramPacket(msg, msg.length);
datagramSocket.receive(inDataPacket); 

在Client创建DatagramSocket对象,将serverAddress和serverPort封装成一个DatagramPacket对象发送到Server。

DatagramSocket datagramSocket = new DatagramSocket();
byte[] msg = new byte[10];
DatagramPacket outDataPacket = new DatagramPacket(msg, 1, serverAddress, serverPort);
datagramSocket.send(outDataPacket); 

Server接收到Client发来的数据报后便可从其中获取clientAddress和clientPort,获取时间后将其发送给Client。

InetAddress clientAddress = inDataPacket.getAddress(); 
int clientPort = inDataPacket.getPort(); 
String time = getTime();
OutDataPacket outDataPacket = new DatagramPacket(time, time.length, clientAddress, clientPort); 
datagramSocket.send(outDataPacket); 

Client获取Server发送的数据报,最后关闭DatagramSocket

String receivedMsg = new String (inDataPacket.getData(), 0, inDataPacket.getLength()); 
datagramSocket.close(); 

两种协议的区别

基于两种协议的Java网络编程可以看出,TCP/IP的通信双方是有建立连接的,而UDP/IP的通信双方并没有连接,而是简单地知道与自己通信的地址和端口。

思考总结

不管是TCP中的Socket、ServerSocket还是UDP中的DatagramSocket,通信双方的端口一般都是不同的。(在网上看到有的人以为通信双方的端口是一样的,认为端口是指哪一条路,双方的信息来往都是在这条路上)就我理解,以TCP为例,多个端口就相当于多个门,Server某个端口A与Client的某个端口B相连,只是说这个Client向Server传递信息时,Client的信息从自己的B端口出去,并从Server的A端口进去。

挖坑

  • TCP/IP、UDP/IP了解多少?
  • Socket呢?Socket上的I/O流?将对象写到输出流后可以不flush吗?
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值