1, 网络模型:
OSI七层,TCP/IP四层
OSI:应用层、表示层、会话层、传输层、网络层、数据链路层、物理层
TCP/IP:应用层、传输层、网际层、主机至网络层
协议:应用层FTP、HTTP、传输层UDP、TCP、网际层IP
2,网络通信要素:
IP地址,端口,传输协议
本机回环地址127.0.0.1,主机名localhost。
InetAddress类,
静态方法getLocalHost获取InetAddress对象。
getByName(String host),获取主机名和ip
getHostAddress(), 返回IP地址字符串形式。
getHostName(),返回IP地址主机名。
端口号,0-65535,系统保留端口0-1024.
协议,UDP面向无连接,TCP面向连接,需要三次握手。
package com.itheima;
import java.net.InetAddress;
public class InetAddress
{
public static void main(String[] args)throws Exception
{
//获取本地ip信息
InetAddress ia = InetAddress.getLocalHost();
String addr = ia.getHostAddress();
String name = ia.getHostName();
System.out.println(addr+"..."+name);
//获取指定主机的ip信息
InetAddress ian = InetAddress.getByName("192.168.1.254");
//获取指定主机名的所有ip信息,[]里可能存在多个 ip地址。
InetAddress[] ialn = InetAddress.getAllByName("www.baidu.com");
}
}
3,Socket
网络通信需要通过Socket才能建立通信。
UDP,使用类DatagramSocket,
public class UdpSend
{
public static void main(String[] args)throws Exception
{
//创建数据流
DatagramSocket ds = new DatagramSocket();
String s = "hahahha test";
byte[] buf = s.getBytes();
//将要发送的数据封装
DatagramPacket dp =
new DatagramPacket(buf, buf.length,InetAddress.getByName("192.168.1.254"),10000);
//通过socket将数据发出。
ds.send(dp);
ds.close();
}
}
public class UdpRecv
{
public static void main(String[] args)throws Exception
{
//创建socket流
DatagramSocket ds = new DatagramSocket(10000);
byte[] buf = new byte[1024];
//用该对象封装数据
DatagramPacket dp = new DatagramPacket(buf, buf.length);
ds.receive(dp);
String ip = dp.getAddress().getHostAddress();
int port = dp.getPort();
String data = new String(dp.getData(), 0, dp.getLength());
System.out.println(ip+"..."+port+"..."data);
ds.close();
}
}
TCP:客户端Socket,服务端ServerSocket。
客户端,Socket(String host, int port)指定接受端的ip和端口号
服务端,ServerSocket(int port),指定监听的端口。
accept()监听并接受此套接字的连接。
Void shutdownInput();标记输入流结尾,
Void shutdownOutput();标记输出流结尾,
TCP的socket流都是用发送端的socket流对象的输入输出方法来通信,
getInputStream(),getOutputStream().
客户端与服务端的连接,先开启服务端,客户端创建socket服务指定主机ip和端口,
write数据到输出流中。服务器端监听端口,通过accept socket流read其中数据,结束后
关闭客户端的流避免客户端一直占用服务端。
TCP客户端程序,
public static void main(String[] args)throws Exception
{
//创建流,并制定要连接到的ip,和端口
Socket s = new Socket("192.168.1.222", 10000);
OutputStream out = s.getOutputStream();
//写入到输出流
out.write("hahha".getBytes());
//读服务器发过来的输入流的信息,输出到屏幕
InputStream in = s.getInputStream();
byte buf = new byte[1024];
int len = in.read(buf);
System.out.println(new String(buf, 0, len));
s.close();
}
服务端程序,
public static void main(String[] args)throws Exception
{
//创建流,并制定要连接到的ip,和端口
ServerSocket ss = new ServerSocket(10000);
Socket s = ss.accept();
//获取发送端的ip
String ip = s.getInetAddress().getHostName();
//读输入流的信息,输出到屏幕
InputStream in = s.getInputStream();
byte buf = new byte[1024];
int len = in.read(buf);
System.out.println(new String(buf, 0, len));
OutputStream out = s.getOutputStream();
//写入到输出流
out.write("shoudao".getBytes());
s.close();
}
如果客户端持续写入,需要在每行后加入换行符并刷新,调用buffer的newLine,和flush(),也可用另一个流,PrintWriter流,PrintWriter(OutputStream, true),加上true可选项后在调用写入方法println时就会自动刷新。
4,URL,
构造函数:URL(String protocol,String host,int port,String file);//根据指定 protocol、host、port号和 file 创建 URL对象。
String getProtocol();//获取协议名称
String getHost();//获取主机名
int getPort();//获取端口号
String getFile();//获取URL文件名
String getPath();//获取此URL的路径部分
String getQuery();//获取此URL的查询部,客户端传输的特定信息
URLConnection ,代表应用程序和URL直接的通信链接
用法,
URL url = new URL(path);
URLConnection conn = url.openConnection();
InputStream in = conn.getInputStream();