一、要想实现网络通信,需要解决的问题?
- 问题一 :如何准确地定位网络上一台或多台主机;定位主机上的特定的应用
- 问题二:找到主机后如何可靠高效地进行数据传输
二、针对上述问题,如何解决?
- 通信要素一:IP地址;端口号
- 通信要素二:通信协议
*三:IP地址
-
- 唯一的标识 Internet 上的计算机(通信实体)
-
- 使用InetAddress类的实例标识具体的一个ip地址
-
- ip地址的分类:
- 角度1: ipv4 vs ipv6
- 角度2:公网地址(万维网(world wide web)使用)和私有地址(局域网使用)
- 私有地址:192.168.开头的就是私有址址。范围即为192.168.0.0–192.168.255.255
- 4.本地回路地址:127.0.0.1 对应的“域名” :localhost
- 5.使用域名,来表示一个具体的ip地址。
- www.atguigu.com
- www.baidu.com
- www.taobao.com
- www.jd.com
- www.vip.com www.360.com
- www.xiaomi.com www.mi.com
四、掌握的内容:
- 获取InetAddress类的实例的两种方式:
getByName(String host) ; getLocalHost();
- 两个常用的方法:
getHostName() / getHostAddress()
五、如何区分一台主机上的不同的进程?
-
使用端口号来区分!
-
不同的进程有不同的端口号
-
范围:0~65535
-
端口分类:
- 公认端口:0~1023。被预先定义的服务通信占用(如:HTTP占用端口80,FTP占用端口21,Telnet占用端口23)
- 注册端口:1024~49151。分配给用户进程或应用程序。(如:Tomcat占用端口8080,MySQL占用端口3306,Oracle占用端口1521等)。
- 动态/私有端口:49152~65535。
六、 具体使用案例
getByName();
//返回一个InetAddress的实例InetAddress的一个对象,标识具体的一个ip地址
inet3.getHostName();
//获取域名
inet3.getHostAddress();
//获取IP地址
七、客户端创建步骤
public void client() {
Socket socket = null;
OutputStream os = null;
try {
//1.创建一个Socket实例,包含要接收数据端的IP地址和端口号
InetAddress inet = InetAddress.getByName("192.168.25.90");
int port = 9090;
socket = new Socket(inet, 9090);
//2.创建一个输出流
os = socket.getOutputStream();
//3.写出数据
os.write("你好,我是客户端!".getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
//4.关闭相关的资源:流、Socket
try {
if (os != null)
os.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if (socket != null)
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
八、服务端创建步骤
public void server() { //服务端
ServerSocket serverSocket = null;
Socket socket = null; //阻塞式的方法 (Scanner 的nextXxx() )
InputStream is = null;
try {
//1. 创建一个ServerSocket的实例
int port = 9090;//指名服务器端自己的端口号
serverSocket = new ServerSocket(port);
//2. 接收来自于客户端的Socket实例
socket = serverSocket.accept();
//3. 创建一个输入流
is = socket.getInputStream();
//4. 读取输入流中的数据,并输出到控制台上
//改进方案:
ByteArrayOutputStream baos = new ByteArrayOutputStream();//内部维护了一个字节数组
byte[] buffer = new byte[10];
int len;
while((len = is.read(buffer)) != -1){
baos.write(buffer,0,len);//将数据写出到ByteArrayOutputStream中的字节数组中
}
System.out.println(baos.toString());//将内部维护的字节数组中的数据转换为字符串输出
} catch (IOException e) {
e.printStackTrace();
} finally {
//5. 关闭相关资源:流、socket关闭
try {
if (is != null)
is.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if (socket != null)
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
//通常都不需要关闭
try {
if (serverSocket != null)
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}