URL:统一资源定位符,也就是说根据URL能够定位到网络上的某个资源,它是指向互联网“资源”的指针。
每个URL都是URI,但不一定每个URI都是URL。这是因为URI还包括一个子类,即统一资源名称(URN),它命名资源但不指定如何定位资源。
2.构造函数
URL(String spec);根据String表示形式创建URL对象;
URL(String protocal,String host,int port,String file);根据指定protocal,host,prot号和file创建URL对象;
import java.net.*;
class URLDemo
{
public static void main(String[] args) throws MalformedURLException
{
URL url = new URL("http://192.168.1.254/myweb/demo.html?name=haha&age=30");
System.out.println("getProtocol() :"+url.getProtocol());
System.out.println("getHost() :"+url.getHost());
System.out.println("getPort() :"+url.getPort());
System.out.println("getPath() :"+url.getPath());
System.out.println("getFile() :"+url.getFile());
System.out.println("getQuery() :"+url.getQuery());
/*int port = getPort();
if(port==-1)
port = 80;
getPort()==-1
*/
}
}
二、URLConnection
1.该类代表应用程序和URL之间的通信链接,此类的实例用于读取和写入此URL引用的资源,通常创建一个URL的连接需要几个步骤:
1)通过URL上调用openConnection方法创建连接对象;该连接对象在向服务端发送请求时自动加载头文件信息;
2)处理设置参数和一般请求属性;
3)使用connect方法建立到远程对象的实际连接;
4)远程对象变为可用;
2.构造函数
URLConnection(URL);构造一个到指定url的url的连接;
3.常用方法:
getInputStream();返回从此打开的连接读取的输入流;
getOutputStream();返回写入此连接的输出流;
三、常见网络结构
1. C/S client/server
特点:
该结构的软件,客户端和服务端都需要编写。
开发成本较高,维护较为麻烦。
好处:
客户端在本地可以分担一部分任务。例如,杀毒软件直接对本机文件进行杀毒。
2. B/S browser/server
特点:
该结构的软件,只开发服务器端,不开发客户端,因为客户端直接由浏览器取代。
开发成本相对低,维护更为简单。
缺点:
所有运算都要在服务端完成。
四、域名解析
1.将主机名翻译成IP地址,需DNS服务器;
2.一般上网先将请求发往DNS,解析出IP地址后再访问解析的IP主机(在访问DNS之前先走本地host文件,127.0.0.1和localhost 的映射关系就在本机上,该文件c:\windows\system32\drives\etc\host文件,通过手动配置该文件,可直接访问,指定网址:
例:在host文件下写入:180.97.33.107 www.baidu.com,当在浏览器访问“www.baidu.com”的时将会直接访问 180.97.33.107IP);
3.应用:可将不想访问的地址,比如:木马网站或软件更新网站等对应到127.0.0.1下,这些网站将不能再本机访问;
/*
需求:上传图片。
客户端。
1,服务端点。
2,读取客户端已有的图片数据。
3,通过socket 输出流将数据发给服务端。
4,读取服务端反馈信息。
5,关闭。
*/
import java.io.*;
import java.net.*;
class PicClient{
public static void main(String[] args)throws Exception {
if(args.length!=1){
System.out.println("请选择一个jpg格式的图片");
return ;
}
File file = new File(args[0]);
if(!(file.exists() && file.isFile())){
System.out.println("该文件有问题,要么补存在,要么不是文件");
return ;
}
if(!file.getName().endsWith(".jpg")){
System.out.println("图片格式错误,请重新选择");
return ;
}
if(file.length()>1024*1024*5){
System.out.println("文件过大,没安好心");
return ;
}
Socket s = new Socket("192.168.1.254",10007);
FileInputStream fis = new FileInputStream(file);
OutputStream out = s.getOutputStream();
byte[] buf = new byte[1024];
int len = 0;
while((len=fis.read(buf))!=-1){
out.write(buf,0,len);
}
//告诉服务端数据已写完
s.shutdownOutput();
InputStream in = s.getInputStream();
byte[] bufIn = new byte[1024];
int num = in.read(bufIn);
System.out.println(new String(bufIn,0,num));
fis.close();
s.close();
}
}
/*
服务端
这个服务端有个局限性。当A客户端连接上以后。被服务端获取到。服务端执行具体流程。
这时B客户端连接,只有等待。
因为服务端还没有处理完A客户端的请求,还有循环回来执行下次accept方法。所以
暂时获取不到B客户端对象。
那么为了可以让多个客户端同时并发访问服务端。
那么服务端最好就是将每个客户端封装到一个单独的线程中,这样,就可以同时处理多个客户端请求。
如何定义线程呢?
只要明确了每一个客户端要在服务端执行的代码即可。将该代码存入run方法中。
*/
class PicThread implements Runnable{
private Socket s;
PicThread(Socket s){
this.s = s;
}
public void run(){
int count = 1;
String ip = s.getInetAddress().getHostAddress();
try{
System.out.println(ip+"....connected");
InputStream in = s.getInputStream();
File dir = new File("d:\\pic");
File file = new File(dir,ip+"("+(count)+")"+".jpg");
while(file.exists())
file = new File(dir,ip+"("+(count++)+")"+".jpg");
FileOutputStream fos = new FileOutputStream(file);
byte[] buf = new byte[1024];
int len = 0;
while((len=in.read(buf))!=-1){
fos.write(buf,0,len);
}
OutputStream out = s.getOutputStream();
out.write("上传成功".getBytes());
fos.close();
s.close();
}catch (Exception e){
throw new RuntimeException(ip+"上传失败");
}
}
}
class PicServer{
public static void main(String[] args) throws Exception{
ServerSocket ss = new ServerSocket(10007);
while(true){
Socket s = ss.accept();
new Thread(new PicThread(s)).start();
}
//ss.close();
}
}