------
Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
OSI参考模型 TCP/IP参考模型
应用层 应用层
表示层
会话层
传输层 传输层
网络层 网际层
数据链路层 主机-网络层
物理层
InetAddress i = InetAdress.getLocalHost()//获取主机地址,需要捕获或抛出未知主机异常
i.toString();
i.getHostAddress();
i.getHostName();
InetAddress i = InetAdress.getByName("122.206.53.115")//()内可以是IP也可以是主机名,获取任意
一台主机,一个主机名可能返回多个IP可以用getAllByName()获取一个网络地址数组
本地回环地址:127.0.0.1主机名:localhost
端口号:
用于标识进程的逻辑地址,不同进程的标识
有效端口:0~65535,其中0~1024是系统使用的保留端口
UDP
将数据,源和目的封装成数据包中,不需要建立连接
每个数据包的大小限制在64K内‘
无连接,不可靠
速度快
TCP
建立连接建立传输通道
连接中进行大数据量传输
通过三次握手完成连接,协议可靠
效率低
Socket
是为网络服务提供的一种机制
通信两端都有Socket
通过Socket进行通信
数据在两个Socket之间通过IO进行传输
UDP发送
//通过DatagramSocket对象创建UDP服务
DatagramSocket ds = new DatagramSocket(45665);
//确定数据并封装成数据包
byte[] buf = "udp message".getBytes();
DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName(122.206.52.111),10000)
//通过socket服务,用send方法将已有数据包发送出去
ds.send(dp);
//关闭资源
UDP接收
//创建UDP socket ,建立端点
DatagramSocket ds = new DatagramSocket(10000);//定义要监听的UDP端口
//定义数据包用于存储数据
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,buf.length);
//通过服务的receive方法将接收到的数据存入数据包中
ds.receive(dp);
//通过数据包的方法获得其中的数据
String ip = dp.getAdress().getHostAdress();
String data = new String(dp.getData(),0,dp.getLength());
int port = dp.getPort();//45665
//关闭资源
ds.close()
UDP聊天程序
class send implements Runnable{
private DatagramSocket ds;
send(DatagramSocket ds){
this.ds = ds;
}
public void run(){
try {
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
String line = null;
while((line=bufr.readLine())!=null){
if("over".equals(line))
break;
byte[] buf = line.getBytes();
DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.102"),12200);
ds.send(dp);
}
// ds.close();
}catch (Exception e) {
throw new RuntimeException("发送失败");
}
ds.close();
}
}
class reve implements Runnable{
private DatagramSocket ds;
reve(DatagramSocket ds){
this.ds = ds;
}
public void run(){
try {
while(true){
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,buf.length);
ds.receive(dp);
String ip = dp.getAddress().getHostAddress();
String data = new String(dp.getData(),0,dp.getLength());
int port = dp.getPort();
System.out.println(ip+"--"+data+"--"+port);
}
} catch (Exception e) {
throw new RuntimeException("接收失败");
}
}
}
class InetCon{
public static void main(String[] args) throws Exception{
new Thread(new reve(new DatagramSocket(12204))).start();
new Thread(new send(new DatagramSocket(12203))).start();
}
}
TCP分客户端和服务端
客户端对应的对象是Socket
服务端对应的对象是Serversocket
客户端:
步骤:
1.创建Socket服务并指定要连接主机的地址和端口
2.获得Socket流中的输出流,将数据写到该流中,通过网络发送给服务端
3.获取Socket流中的输入流,将服务端反馈的数据获取到,并打印到控制台
4.关闭客户端资源
//创建客户端的socket服务,指定目的主机和端口
Socket s = new Socket("192.168.1.1",19993);
为了发送数据,应该获得都socket流的输出流
OutputStream out = s.getOutputStream();
out.write(".....hello".getBytes());
s.close();
服务端:
1.建立服务端的Socket服务,ServerSocket();
并监听一个端口
2.获取连接的客户端对象
通过ServerSocket的accept方法。没有连接就等,这个方法是阻塞式的。
3.客户端发过来数据,那么服务端就要使用对应的客户端对象,并获取到该客户端对象的读取流来读取发过来的数据,并打印在控制台上。
4.关闭客户端
//建立服务端的Socket服务,并监听一个端口
ServerSocket ss = new ServerSocket(10052);
//通过ServerSocket的accept方法获取连接的客户端对象
Socket s = ss.accept();
//获得客户端发送的数据,要使用客户端对象的读取流来读取数据
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
//关闭客户端
s.close();
TCP服务器小程序
class InetServer
{
public static void main(String[] args) throws IOException
{
ServerSocket ss = new ServerSocket(10009);
Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+" is connected");
OutputStream out = s.getOutputStream();
out.write("欢迎+\r\n".getBytes());
out.flush();
s.close();
ss.close();
}
}
在客户端与服务端的通信交互时,如果用的是字符流的缓冲区,记得写入之后要flush(),
readLine的结束符是"\r\n";
客户端的Socket.close()是将socket流中加-1,使服务端的readLine方法停下,导致循环结束
PrintWriter的用的写入方法是println()
客户端上传文本文件时,客户端的readLine所在循环可以自动结束,服务端不可以,需要加入标记结束循环,标记可以是时间戳,也可以在末尾直接加"-1";
shutdownOutput();可以关客户端的输出流,在流中加入结束标记-1
浏览器作为客户端时,服务端的输出流要在结束时加-1,并且要记得刷新流
URL统一资源定位符
URL url = new URL("");
String getFile()
获取URL的文件名//带参数
String getHost()
获取URL的主机名
String getPath()
获取URL的路径部分
String getPort()
获取URL的端口号
String getProtocol()
获取URL的协议名称
String getQuery()
获取URL的查询部
URLConnection conn = url.openConnection();
InputStream in = coon.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
String s = new String(buf,0,len);
浏览器和服务器在通信的数据包都包含一个数据头
URLConnection用的应用层协议,不含数据包的头部
域名解析
c:\windows\systems\drivers\ext\host
中存放了本机的默认域名映射,可以用来屏蔽网址
域名解析先找本地,再找域名服务器中的地址