Java之网络编程初步探索
最近一直在啃Java,学下来一天,代码也敲了不少,但晚上回寝室的时候总感觉头晕,仔细想想,脑子一团浆糊,还是得整理一下,不然真的学过了就忘,虽然本人十分懒,但还是得强迫一下自己才能进步。
整个文章分为以下几个部分:
1.一些基本协议的介绍
2.InetAddress类介绍
3.URL网络编程
4.TCP网络编程
5.总结
一些基本协议的介绍
1.TCP协议
TCP(Transmission Control Protocol),指的是传输控制协议,它是网络传输层的协议,主要负责数据的分组和重组。TCP协议提供了一种可靠的数据传输服务,它是面向连接的,大多数的网络应用程序都使用TCP来实现传输层。它可以保证数据传送的时间、顺序和内容的准确无误。但是使用TCP要大量的网络开销,所有如果希望实现高效率的传输,那么TCP就不行了。TCP所提供的服务主要有以下特点:
- 面向连接的传输
- 端到端的通信
- 高可靠性,确保传输数据的正确性,不出现丢失或乱序
- 全双工方式传输
- 采用字节流方式,即以字节为单位传送字节序列
- 紧急数据传送功能
2.IP协议
IP(Internet Protocol)网络之间互联的协议,简称为网协,也就是为计算机网络相互连接进行通信而设计的协议。在因特网中,它是能使连接到网上的所有计算机网络实现相互通信的一套规则,任何厂家生产的计算机系统,只要遵循IP协议就可以与因特网互联互通。
IP地址是一个32位(IPv4)或128位(IPv6)的无符号数字,使用4组数字表示一个固定的编号,数字之间用一个点号隔开,例如192.168.168.168就代表网络中一个计算机唯一的地址编号。
3.UDP协议
UDP(User Datagram Protocol),指的是用户数据报协议。它和TCP一样,都是网络传输层上的协议,但它与TCP有本质的区别。使用UDP,不保证数据一定能到达目的地,也不保证到达的顺序,但是UDP占用资源比较少,所有一般使用在一些可靠性要求比较低的网络应用上,比如网络视频会议、在线影视和聊天室等音频、视频数据传输。
4.端口
端口(Port)可以理解成计算机与外界通信的窗户。网络上的一台计算机可以提供多个服务,例如web服务,ftp服务,Telnet服务等,那么该如何识别这些服务呢?单靠一个IP地址肯定是不行的,应该一个计算机就只有一个唯一的IP地址,那么我们就可以通过IP+Port的形式来区分,当一个信息到达时,根据其请求的端口号,就可以判断出应该提供哪个服务了。
一些常见的端口有:HTTP:80 FTP:21 Telnet:23 SMTP:25
5.套接字
套接字(Socket)是支持TCP/IP网络通信的基本操作单元。可以看做是不同主机之间的进程进行双向通信的端面点,简单说就是通信的双方的一种约定,用套接字中的相关函数来完成通信过程。某个程序将一段信息写入套接字,该套接字就会把这段信息发给另一个套接字,就像电话线的两端一样,这样另一端的程序就能通过另一端的套接字收到这段信息,所以套接字编程也成为Socket编程。
6.Java.net包
在Java的API中,Java.net包是被用来提供网络服务的。
大致有这么些接口和类。可以分为以下两类:
- 低级API,用于处理网络地址(也就是网络标识符,如IP地址)、套接字(也就是基于双向数据通信机制)和接口(用于描述网络接口)。
- 高级API,用于处理URI(表示统一资源标识符)、URL(表示统一资源定位符)、URLConnection连接(表示到URL所指向资源的连接)等。
InetAddress类介绍
InetAddress表示互联网协议(IP)地址,用于描述和包装一个Internet IP地址。
InetAddress没有构造方法,可以通过以下三个方法返回一个InetAddress实例:
- getLocalHost():返回本地地址的实例
- getAllByName(String host):返回封装host地址的InetAddress实例数组
- getByName(String host):返回封装host地址的InetAddress实例,其中host可以是域名或者是一个合法的IP地址。
InetAddress有一些常用的方法可以查阅API文档,下面来一段代码看看常用的方法
public class Test01 {
public static void main(String[] args) {
InetAddress ia = null;
try {
// 返回本地主机
ia = InetAddress.getLocalHost();
} catch(UnknownHostException e) {
e.printStackTrace();
}
System.out.println("本机的主机名为: " + ia.getHostName());
System.out.println("本机的IP为: " + ia.getHostAddress());
}
}
输出为
本机的主机名为: liu-PC
本机的IP为: 192.168.56.1
URL网络编程
URL是统一资源定位符,由两部分组成:协议标识和资源名称。
URL类提供多个方法,可以获取URL对象的协议、主机号、端口号、路径、查询字符串、文件名和资源引用。
URLConnection类用来表示与URL建立的通信连接,调用URL类的openConnection()方法可以获得URLConnection对象,获得对象后,可以调用该对象的connect()方法来连接远程资源。连接远程资源后,就可以执行相关操作,包括查询HTTP请求头信息、访问资源数据等,以及写入相关内容。
public class Test02 {
public static void main(String[] args) throws IOException{
URL url = null;
URLConnection urlc = null;
try {
url = new URL("http://www.codeliu.com");
// URLConnection为抽象类,不能实例化
//URLConnection urlc = new URLConnection(url);
urlc = url.openConnection();
} catch (MalformedURLException e) {
e.printStackTrace();
}
// 输出URL对象的协议
System.out.println("protocol = " + url.getProtocol());
// 输出URL对象的主机号和端口号
System.out.println("authority = " + url.getAuthority());
// 输出URL的主机名
System.out.println("host = " + url.getHost());
// 输出URL的端口号 ,未设置端口号,则返回-1
System.out.println("port = " + url.getPort());
// 建立连接
urlc.connect();
System.out.println("content = " + urlc.getContent());
System.out.println(urlc.getURL());
}
}
TCP网络编程
通过TCP进行通信的双方成为服务端和客户端。服务端和客户端可是是两台计算机,也可以是一台计算机。服务器端和客户端运行的程序有所不同,下面会详细介绍。
套接字之间的连接过程可以分为三个步骤:服务器监听,客户端请求,连接确认。
在Java.net包中,有一个Socket类,用来建立Socket套接字,还有一个ServerSocket类,用在服务器端,里面的accept()方法,用来监听和接收客户端的连接请求。
服务器端的设计
服务器端要同时用到Socket类和ServerSocket类。通常有以下步骤:
- 创建类ServerSocket的实例对象,调用构造方法初始化进行连接的端口号。
- 调用ServerSocket类的方法accept(),等待监听客户端的连接请求,当和客户端建立连接后,accept()方法将返回服务器端的Socket对象,通过该Socket可以和客户端进行数据通信。
- 通过调用服务器端Socket的方法getInputStream()和getOutputStream(),获得对应的输入流和输出流。
- 通过获得的输入流和输出流与客户端进行数据通信,并处理从客户端获得的数据以及要向客户端发送的数据。
- 数据传输结束后,关闭输入流、输出流和套接字。
public class Test03 {
public static void main(String[] args) throws IOException{
ServerSocket server = null;
// 创建ServerSocket实例,参数为监听的端口号
server = new ServerSocket(80);
System.out.println("服务器已启动,正在等待连接....");
Socket client = null;
// 阻塞,等待客户端连接
client = server.accept();
System.out.println("客户端建立连接");
// 获得Socket连接的字节输入流并转换为缓冲字节流
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
// 获取Socket连接的打印输出流
PrintWriter out = new PrintWriter(client.getOutputStream());
while(true) {
// 读取一行内容
String str = in.readLine();
System.out.println(str);
out.println("已接收到...");
out.flush();
if(str.equals("end")) {
break;
}
}
in.close();
out.close();
client.close();
server.close();
}
}
客户端的设计
客户端程序只需要用到java.net.Socket类。在服务器/客户端的网络应用程序中,每次的TCP连接请求都会由客户端向服务器端发起。客户端建立通常有以下4个步骤
- 创建Socket类实例,在创建Socket实例时要指定服务器的主机名以及要进行连接的端口号(此端口号一定要与服务器的ServerSocket实例所监听的端口号一致)。
- 调用客户端Socket的方法getInputStream()和getOutputStream()获得该Socket对应的输入流和输出流。
- 通过获得输入流和输出流与服务器进行数据通信,并处理从服务器获得的数据以及要向服务器发送的数据。
- 数据传输结束后,关闭输入流、输出流和套接字。
public class WebClientDemo {
public static void main(String[] args) throws IOException {
// 创建Socket端口,连接IP的80端口
Socket client = new Socket("www.codeliu.com", 80);
System.out.println("服务器IP是" + client.getInetAddress());
System.out.println("服务器端口号是" + client.getPort());
System.out.println("客户机IP是" + client.getLocalAddress());
System.out.println("客户机端口号是" + client.getLocalPort());
}
}
看完上面是不是有点懵懵的,下面看看我画的一张图应该就更好理解了
总结
本文讲述的只是一些最基本的知识点,也不全面,因为我也是第一次学习Socket编程,写这篇文章只是希望能记录一下知识点,方便以后复习查阅,上面这点代码对于理解TCP编程肯还不够,我还写了一个小小的服务端客户端通信的示例,对理解TCP编程有一定的帮助,因为代码太多,就不贴了,不然篇幅太长了。如果错误和意见,欢迎批评指正。
欢迎大家访问我的个人博客https://www.codeliu.com
不定时更新一些Java方法的文章,欢迎友链!