网络编程(狭义):在两个或两个以上的设备(例如计算机)之间传输数据;程序员所作的事情就是把数据发送到指定的位置,或者接收到指定的数据。
一:网络通讯方式
在现有的网络中,网络通讯的方式主要有两种:
1、 TCP(传输控制协议)方式
TCP方式就类似于拨打电话,使用该种方式进行网络通讯时,需要建立专门的虚拟连接,然后进行可靠的数据传输,如果数据发送失败,则客户端会自动重发该数据。
2、 UDP(用户数据报协议)方式
UDP方式就类似于发送短信,使用这种方式进行网络通讯时,不需要建立专门的虚拟连接,传输也不是很可靠,如果发送失败则客户端无法获得。
UDP和TCP协议的区别:
二:基于url的网络编程
1.创建一个URL
为了表示URL, java.net中实现了类URL。我们可以通过如下的构造方法等来初始化一个URL对象(只显示出部分构造函数,其他可以参考java api):
1、URL(String spec)
根据 String 表示形式创建 URL 对象。
URL url = new URL("http://www.baidu.com");
2、URL(String protocol, String host, int port, String file)
根据指定 protocol、host、port 号和 file 创建 URL 对象。
URL url = new URL("http", "www.gamelan.com", "/pages/Gamelan.net. html");
2. 解析一个URL
一个URL对象生成后,其属性是不能被改变的,但是我们可以通过类URL所提供的方法来获取这些属性:
public String getProtocol() 获取该URL的协议名。
public String getHost() 获取该URL的主机名。
public int getPort() 获取该URL的端口号,如果没有设置端口,返回-1。
public String getFile() 获取该URL的文件名。
public String getRef() 获取该URL在文件中的相对位置。
public String getPath() 获取该URL的路径
三.从URL读取WWW网络资源
当得到一个URL对象后,就可以通过它读取指定的WWW资源。这时我们将使用URL的方法openStream(),其定义为:
InputStream openStream();
方法openSteam()与指定的URL建立连接并返回InputStream类的对象以从这一连接中读取数据。
URL url = new URL("http://www.baidu.com");
// 使用openStream得到一输入流并由此构造一个BufferedReader对象
BufferedReader br = new BufferedReader(new InputStreamReader(
url.openStream()));
String line = null;
while (null != (line = br.readLine())) {
System.out.println(line);
}
br.close();
四:基础类:InetAddress类
该类的功能是代表一个IP地址,并且将IP地址和域名相关的操作方法包含在该类的内部。
InetAddress 类没有明显的构造函数,为生成一个InetAddress对象,必须运用一个可以返回一个该类实例的静态类。对于InetAddress,三个方法 getLocalHost( )、getByName( )以及getAllByName( )可以用来创建InetAddress的实例 。
InetAddress类运用:
public class InetAddressDemo {
public static void main(String[] args) {
try {
// 使用域名创建对象
InetAddress inet = InetAddress.getByName("www.163.com");
// 获取IP地址
System.out.println(inet.getHostAddress());
// 获取主机名
System.out.println(inet.getHostName());
} catch (Exception e) {
e.printStackTrace();
}
}
}
其中:DNS域名解析:当我们访问localhost时,因为自己本机上配置了127.0.0.1,所以就先访问本机的,如果本机上没配置,就会去访问局域网或广域网上DNS服务器上的数据找到IP地址,然后返回给浏览器再接着访问服务器。
五:UDP编程
在Java API中,实现UDP方式的编程,包含客户端网络编程和服务器端网络编程,主要由两个类实现,分别是:
类DatagramSocket:此类表示用来发送和接收数据报包的套接字。简单的说就是DatagramSocket实现的就是发送数据时的发射器,以及接收数据时的监听器的角色。
类DatagramPacket:此类表示数据报包。在UDP方式的网络编程中,无论是需要发送的数据还是需要接收的数据,都必须被处理成DatagramPacket类型的对象。
UDP发送端:
public class InetAddressDemo {
public static void main(String[] args) throws IOException{
/*
* 创建UDP传输的发送端。
* 思路:
* 1,建立udp的socket服务。
* 2,将要发送的数据封装到数据包中。
* 3,通过udp的socket服务将数据包发送出去。
* 4,关闭socket服务。
*/
// 1,udpsocket服务。使用DatagramSocket对象。
DatagramSocket ds = new DatagramSocket(8888);
// 2,将要发送的数据封装到数据包中。
String str = "udp传输演示数据!";
// 使用DatagramPacket将数据封装到的该对象包中。
byte[] buf = str.getBytes();
DatagramPacket dp = new DatagramPacket(buf, buf.length,
InetAddress.getByName("192.168.1.118"), 10000);
// 3,通过udp的socket服务将数据包发送出去。使用send方法。
ds.send(dp);
// 4,关闭资源。
ds.close();
}
}
UDP接收端:
public class UDPReceDemo {
public static void main(String[] args) throws IOException {
/*
* 建立UDP接收端的思路。
* 1,建立udp socket服务,因为是要接收数据,必须要明确一个端口号。
* 2,创建数据包用于存储接收到的数据。方便用数据包对象的方法解析这些数据.
* 3,使用socket服务的receive方法将接收的数据存储到数据包中。
* 4,通过数据包的方法解析数据包中的数据。
* 5,关闭资源
*/
// 1,建立udp socket服务。
DatagramSocket ds = new DatagramSocket(10000);
// 2,创建数据包。
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf, buf.length);
// 3,使用接收方法将数据存储到数据包中。
ds.receive(dp);// 阻塞式的。
// 4,通过数据包对象的方法,解析其中的数据,比如,地址,端口,数据内容。
String ip = dp.getAddress().getHostAddress();
int port = dp.getPort();
String text = new String(dp.getData(), 0, dp.getLength());
System.out.println(ip + ":" + port + ":" + text);
// 5,关闭资源。
ds.close();
}
}
六:TCP编程
在Java语言中,对于TCP方式的网络编程提供了良好的支持,在实际实现时,以java.net.Socket类代表客户端连接,以java.net.ServerSocket类代表服务器端连接。
客户端:
public class TCPClient {
public static void main(String[] args) throws IOException,
ClassNotFoundException {
// 客户端发数据到服务端
/*
* Tcp传输,客户端建立的过程。
* 1,创建tcp客户端socket服务。使用的是Socket对象。
* 建议该对象一创建就明确目的地。要连接的主机。
* 2,如果连接建立成功,说明数据传输通道已建立。 该通道就是socket流 ,是底层建立好的。
* 既然是流,说明这里既有输入, 又有输出。 想要输入或者输出流对象,可以找Socket来获取。
* 可以通过getOutputStream(),和getInputStream()来获取两个字节流。
* 3,使用输出流,将数据写出。
* 4,关闭资源。
*/
Socket s = new Socket("192.168.1.110", 10002);
OutputStream out = s.getOutputStream();
out.write("TCP演示数据".getBytes());
// 读取服务端返回的数据,使用socket读取流。
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
System.out.println(new String(buf, 0, len));
out.close();
in.close();
s.close();
}
}
服务端:
public class TCPServer {
public static void main(String[] args) throws IOException,
ClassNotFoundException {
/*
* 建立tcp服务端的思路:
* 1,创建服务端socket服务。通过ServerSocket对象。
* 2,服务端必须对外提供一个端口,否则客户端无法连接。
* 3,获取连接过来的客户端对象。
* 4,通过客户端对象获取socket流读取客户端发来的数据,并打印在控制台上。
* 5,关闭资源。关客户端,关服务端。
*/
// 监听端口号
int port = 10002;
// 建立连接
ServerSocket serverSocket = new ServerSocket(port);
// 获得连接
Socket s = serverSocket.accept();
// 接收客户端发送内容
InputStream in = s.getInputStream();
String ip = s.getInetAddress().getHostAddress();
byte[] buf = new byte[1024];
int len = in.read(buf);
String text = new String(buf, 0, len);
System.out.println(ip + "---" + text);
// 使用客户端socket对象的输出流给客户端返回数据
OutputStream out = s.getOutputStream();
out.write("收到数据".getBytes());
// 关闭资源
in.close();
out.close();
s.close();
serverSocket.close();
}
}