------------android培训、java培训、期待与您交流! -------------
1、软件之间通信条件:
a.找到对方IP b.数据要发送到对方指定的应用程序上,为了表示这些程序,所以给这些网络应用程序都用数字进行标示。 为了方便称呼这个数字,叫做端口,逻辑端口。 c.定义通信规则。既成为协议,通用为TCP/IP2、本地回环地址:127.0.0.1(可以测试网卡用,ping)
IPV6(包含数字和字母)
端口号的范围为0---65535之间,0----1023之间的端口数是用于一些知名的网络服务和应用
Web服务端口一般是80.
3、网络参考模型:
每一层都有自己的封装数据规则,以此区分数据包。一层层传递,层层封,层层拆。
WEB开发在应用层(URL、FTP、HTTP)混;
现在是在传输层(TCP)和网际(IP)层混;
4、Socket:
l Socket就是为网络服务提供的一种机制。
l 通信的两端都有Socket。
l 网络通信其实就是Socket间的通信。
l 数据在两个Socket间通过IO传输。
Socket是网络驱动层提供给应用程序编程的接口和一种机制
可以吧Socket比喻成是一个港口码头。应用程序只要把货物放到港口码头上,就算完成了货物的运送。应用程序只需等待货物到达码头后,将货物取走
Socket在应用程序中创建,通过一种绑定机制与驱动程序建立关系,告诉自己所对应的IP和Port。
5、InetAddress
主要的方法:
InetAddress:构造方法私有,不能直接创建对象。
InetAddressgetByName(String host):在给定主机名的情况下确定主机的ip地址。
InetAddressgetLocalHost():返回本地主机。
InetAddress[]getAllByName(String host)
ip.getHostAddress(),
ip.getHostName()
InetAddress[] getAllByName(String host) throws UnknownHostException
对应一个name对应多个主机的状态(例如百度),最好获取IP不取name
网络通信其实就是Socket间的通信
- public class InetAddressDemo {
- /**
- * @param args
- * @throws IOException
- */
- public static void main(String[] args) throws IOException {
- // TODO Auto-generated method stub
- InetAddress local = InetAddress.getLocalHost();
- System.out.println(local.toString());
- //virtor/192.168.12.101,还有getHostAddress();getHostName()两个方法
- InetAddress[] baidu = InetAddress.getAllByName("www.baidu.com");//可见百度两个服务器,不过不知道真的假的
- for(InetAddress ip1 :baidu){
- System.out.println(ip1.toString());
- // 打印结果:www.baidu.com/61.135.169.125
- // www.baidu.com/61.135.169.105
- }
- }
- }
6、传输协议:
在传输层常用的两个协议为UDP和TCP
UDP
l 将数据及源和目的封装成数据包中,不需要建立连接
l 每个数据报的大小在限制在64k内
l 因无连接,是不可靠协议、容易丢包
l 不需要建立连接,速度快
相当于到邮局寄邮件,对方的地址、姓名要写上。但是接收人不一定及时接收。
(qq聊天工具、飞信、凌波等)
TCP
l 建立连接,形成传输数据的通道。
l 在连接中进行大数据量传输
l 通过三次握手完成连接,是可靠协议
l 必须建立连接,效率会稍低
相当于打电话
7、UDP传输
DatagramSocket与DatagramPacket
l 建立发送端,接收端。
l 建立数据包。
l 调用Socket的发送接收方法。
l 关闭Socket。
l 发送端与接收端是两个独立的运行程序。
Udp发送、接收代码示例
- import java.net.*;
- /*
- 需求:通过udp传输方式,将一段文字数据发送出去。,
- 定义一个udp发送端。
- 思路:
- 1,建立updsocket服务。
- 2,提供数据,并将数据封装到数据包中。
- 3,通过socket服务的发送功能,将数据包发出去。
- 4,关闭资源。
- */
- class UDPSend{
- public static void main(String[] args) throws Exception {
- //1,创建udp服务。通过DatagramSocket对象。
- DatagramSocket ds = new DatagramSocket(8888);
- //2,确定数据,并封装成数据包。DatagramPacket(byte[] buf, int length, InetAddress address, int port)
- byte[] buf = "董方宇".getBytes();
- DatagramPacket dp =
- new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.254"),10000);
- //3,通过socket服务,将已有的数据包发送出去。通过send方法。
- ds.send(dp);
- //4,关闭资源。
- ds.close();
- }
- }
- /*
- 需求:
- 定义一个应用程序,用于接收udp协议传输的数据并处理的。
- 定义udp的接收端。
- 思路:
- 1,定义udpsocket服务。通常会监听一个端口。其实就是给这个接收网络应用程序定义数字标识。
- 方便于明确哪些数据过来该应用程序可以处理。
- 2,定义一个数据包,因为要存储接收到的字节数据。
- 因为数据包对象中有更多功能可以提取字节数据中的不同数据信息。
- 3,通过socket服务的receive方法将收到的数据存入已定义好的数据包中。
- 4,通过数据包对象的特有功能。将这些不同的数据取出。打印在控制台上。
- 5,关闭资源。
- */
- class UDPRece{
- public static void main(String[] args) throws Exception{
- //1,创建udp socket,建立端点。这里必须定义监听的端口,其实就是给网络应用程序定义数字标识。
- DatagramSocket ds = new DatagramSocket(10000);
- while(true){
- //2,定义数据包。用于存储数据。
- byte[] buf = new byte[1024];
- DatagramPacket dp = new DatagramPacket(buf,buf.length);
- //3,通过服务的receive方法将收到数据存入数据包中。
- ds.receive(dp);//阻塞式方法。没接到数据则一直等待
- //4,通过数据包的方法获取其中的数据。
- String ip = dp.getAddress().getHostAddress();
- String data = new String(dp.getData(),0,dp.getLength());
- int port = dp.getPort();
- System.out.println(ip+"::"+data+"::"+port);
- }
- //5,关闭资源
- s.close();
- }
- }
UDP练习:聊天程序
- /*一个发送端,一个接收端,实现聊天*/
- import java.io.*;
- class UdpSend2
- {
- public static void main(String[] args) throws Exception
- {
- DatagramSocket dg = new DatagramSocket(18000);
- //读取键盘录入
- BufferedReader bufr =
- new BufferedReader(new InputStreamReader(System.in));
- String line = null;
- //192.168.1.255是这个网段的广播地址,用它就能实现局域网群聊。
- InetAddress ip = InetAddress.getByName("192.168.1.255");
- DatagramPacket dp = null;
- while((line=bufr.readLine())!=null)
- {
- if("over".equals(line))
- break;
- byte [] buf = ("sender:"+line).getBytes();
- dp = new DatagramPacket(buf,0,buf.length,ip,17000);
- dg.send(dp);
- }
- dg.close();
- }
- }
- class UdpRece2
- {
- public static void main(String[] args) throws Exception
- {
- DatagramSocket dg = new DatagramSocket(17000);
- byte[] buf = new byte[1024];
- DatagramPacket dp = new DatagramPacket(buf,buf.length);
- while(true)
- {
- dg.receive(dp);
- String ip = dp.getAddress().getHostAddress();
- String data = new String(dp.getData(),0,dp.getLength());
- System.out.println("("+ip+":"+dp.getPort()+")"+data);
- //System.out.println(new String(buf,0,dp.getLength()));
- }
- //dg.close();因为无限循环,这句读不到
- }
- }
- /*实现多线程,一个窗口就可以!
- 编写一个聊天程序
- 有接受数据的部分,和发数据的部分。
- 这两部分需要同时执行。那就需要用到多线程技术。
- 一个线程控制收,一个线程控制发。
- 因为收和发动作是不一致的,所以要定义两个run方法,
- 而且run方法要封装到不同的类中。
- */
- /*
- 编写一个聊天程序。
- 有收数据的部分,和发数据的部分。
- 这两部分需要同时执行。
- 那就需要用到多线程技术。
- 一个线程控制收,一个线程控制发。
- 因为收和发动作是不一致的,所以要定义两个run方法。
- 而且这两个方法要封装到不同的类中。
- */
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.net.DatagramPacket;
- import java.net.DatagramSocket;
- import java.net.InetAddress;
- public class ChatDemo {
- /**
- * @param args
- * @throws IOException
- */
- public static void main(String[] args) throws IOException {
- // TODO Auto-generated method stub
- //创建两个Udp的socket对象,一个接收端一个发送端
- DatagramSocket send = new DatagramSocket();
- DatagramSocket rece = new DatagramSocket(10086);
- //创建两个匿名的线程对象,传入实现Runnable接口覆盖run方法的两个匿名聊天对象,开启多线程。
- new Thread(new SendMes(send)).start();
- new Thread(new Rece(rece)).start();
- }
- }
- class SendMes implements Runnable{
- private DatagramSocket send ;
- SendMes(DatagramSocket ds){
- this.send = ds;
- }
- public void run(){
- //把键盘输入流封装成对象
- BufferedReader br =
- new BufferedReader(new InputStreamReader(System.in));
- String line = null;
- try {
- while((line = br.readLine())!= null){
- byte[] buf = line.getBytes();
- InetAddress id = InetAddress.getByName("127.0.0.1");
- DatagramPacket dp =
- new DatagramPacket(buf, 0,buf.length,id , 10086);//建一个数据包用来封装键盘录入的数据
- send.send(dp); //通过send方法把数据包发送出去
- if(line.equals("886")) { //必须在最后判断,不然下边都关socket了,怎么把886发给接收端!
- System.out.println("不聊了");
- send.close();
- break;
- }
- }
- send.close();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- //send.close();
- }
- }
- class Rece implements Runnable{
- private DatagramSocket rese;
- public Rece(DatagramSocket ds){//接收端的Udp要侦听端口,所以传入的DatagramSocket对象要指定端口
- this.rese = ds;
- }
- public void run(){
- while(true){
- byte [] buf = new byte[1024];
- DatagramPacket dp = new DatagramPacket(buf,buf.length);//建一个数据包,用来接收发送端发送的数据
- try {
- rese.receive(dp);//接收数据,封装到dp包中!
- String ip = dp.getAddress().toString();//获取ip
- String data = new String(dp.getData(),0,dp.getLength());//获取数据并封装成String
- if(data.equals("886"))//同样放在最后
- {
- System.out.println(ip+"....离开聊天室");
- rese.close();
- break;
- }
- System.out.println("ip: "+ip+" data: "+data);
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- }
9、bindExcetion绑定异常。端口被使用了
10、192.168.1.0是网络地址;192.168.1.255是广播地址;
11、TCP传输
Socket和ServerSocket
建立客户端和服务器端
建立连接后,通过Socket中的IO流进行数据的传输
关闭socket
同样,客户端与服务器端是两个独立的应用程序。
演示tcp的传输的的客户端和服务端的互访。
- /*
- 需求:客户端给服务端发送数据,服务端收到数据后,给客户端反馈信息。
- 客户端:
- 1.建立socket服务,指定要连接的主机和端口
- 1.获取Socket流中的输出流,将数据写入到该流中,通过网络发送给服务端。
- 3.获取socket流中的输入流,将服务端反馈的数据获取到,并打印,
- 4.关闭客户端资源。
- */
- import java.net.*;
- import java.lang.Exception;
- import java.io.*;
- class Client
- {
- public static void main(String[] args) throws Exception
- {
- Socket s = new Socket("127.0.0.1",10086);
- OutputStream ops = s.getOutputStream();
- ops.write("服务器你好".getBytes());
- InputStream ips = s.getInputStream();
- byte[] buf = new byte[1024];
- int len = ips.read(buf);
- System.out.println(new String(buf,0,len));
- s.close();
- }
- }
- class Server
- {
- public static void main(String[] args)throws Exception
- {
- ServerSocket ss = new ServerSocket(10086);
- Socket s = ss.accept();
- InputStream ips = s.getInputStream();
- byte[] buf = new byte[1024];
- int len = ips.read(buf);
- System.out.println(s.getInetAddress().toString()+"-----connecting");
- System.out.println(new String(buf,0,len));
- OutputStream ops = s.getOutputStream();
- Thread.sleep(5000);
- ops.write("哥们,我收到了".getBytes());
- s.close();
- }
- }
示例代码:需求:键盘录入数据通过服务端转成大写形式。
- /*
- 建立一个文本转换服务器。
- 客户端给服务端发送文本,服务端会将文本转成大写再返回给客户端。
- 而且,客户端可以不断的进行文本转换。当客户端输入over,转换就结束。
- 分析:
- 客户端:
- 既然是操作设备上的数据,那么就可以使用io技术,并按照IO的操作规律来思考。
- 源:键盘录入
- 目的:网络设备,也就是网络输出流,
- 而且操作的是文本数据,可以选择字符流。
- 步骤:
- 1,建立服务
- 2.获取键盘录入
- 3,将数据发给服务端。
- 4.获取服务端返回的大写数据。
- 5.结束,关闭资源。
- 都是文本数据,可以使用字符流进行操作。同时提高效率,要加入缓冲。
- */
- /*练习总结:这个也借鉴了毕老师和一位写的很优秀的博客。
- 仔细分析使用缓冲流和打印流的区别才发现有很大不同。下面的代码有注解,可以随时复习。真想说,多么好的打印流啊
- */
- import java.net.*;
- import java.lang.Exception;
- import java.io.*;
- class Client1
- {
- public static void main(String[] args) throws Exception
- {
- Socket s = new Socket("127.0.0.1",10086);
- //输入流封装成对象
- BufferedReader bur =
- new BufferedReader(new InputStreamReader(System.in));
- //定义一个socket读取流,读取服务端返回的信息。
- BufferedReader bure =
- new BufferedReader(new InputStreamReader(s.getInputStream()));
- //定义目的,将数据写入socket输出流,发给服务器。
- //BufferedWriter bufOut =
- //new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
- PrintWriter pw =new PrintWriter(s.getOutputStream(),true);
- String line = null;
- while((line = bur.readLine())!=null){//阻塞位置1,等待键盘录入,没有数据则等待
- if("over".equals(line)){
- s.close();
- break;
- }
- //bufOut.write(line);
- //bufOut.newLine();//没有这一句,则阻塞2的readline不会返回字符,
- //bufOut.flush();//没有这一句,则数据留在缓冲区中,阻塞2同样阻塞。
- //pw.write(line+"\r\n");
- pw.println(line);//println的效果很有意思,它是将数据write写入到流中,并且在对方的控制台打印!一句顶上边三句,也不用在line后加换行符了
- //pw.flush();//b不是必须刷,因为new PrintWriter(s.getOutputStream(),true);调用println的时候会自动刷新
- String l = bure.readLine();//阻塞位置3,想readLine接收的数据必须有换行符,要么加"\r\n"要么newline()。要么用打印流的换行打印
- System.out.println("server:"+l);
- }
- s.close();//这个流关了,其他源自于他的也都关了
- bur.close();
- }
- }
- class Server1
- {
- public static void main(String[] args) throws Exception{
- ServerSocket sso = new ServerSocket(10086);
- Socket s = sso.accept();
- System.out.println(s.getInetAddress().toString()+"---connecting");
- //目的,socket输出流,将大写数据写入到socket输出流,并发送给客户端。
- //BufferedWriter bufOut =
- //new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
- PrintWriter pw =
- new PrintWriter(s.getOutputStream(),true);// 通过现有的 OutputStream 创建新的 PrintWriter。调用println的时候会自动刷新
- //读取socket读取流中的数据。
- BufferedReader bur =
- new BufferedReader(new InputStreamReader(s.getInputStream()));
- String line =null;
- while((line = bur.readLine())!=null){//阻塞位置2,没有数据+换行符(win中是“\r\n”)则等待,尤其注意换行符
- System.out.println("收到客户端发的数据:"+line);
- //pw.println("收到客户端发的数据:"+line);
- //bufOut.write(line.toUpperCase());
- //bufOut.newLine();
- //bufOut.flush();
- String l = line.toUpperCase();
- pw.println(l);
- //pw.write(l+"\r\n");
- //pw.flush();
- }
- sso.close();
- }
- }
示例代码:上传图片(使用IO字节流)
- /*
- 需求:上传图片
- */
- /*
- 客户端:
- 1.服务端点
- 2.读取客户端已有的图片数据
- 3.通过socket的输出流将数据发给服务端。
- 4.读取服务端反馈信息。
- 5.关闭。
- */
- import java.io.*;
- import java.net.*;
- class PicClient1
- {
- public static void main(String[] args) throws Exception
- {
- Socket s = new Socket("192.168.1.13",10086);
- FileInputStream fis = new FileInputStream(".d:\\123.jpg");
- 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 inLen = in.read(buf);
- System.out.println("Server:"+new String(buf,0,inLen));
- fis.close();
- s.close();
- }
- }
- /*
- 服务端:
- */
- class PicServer1
- {
- public static void main(String[] args) throws Exception
- {
- ServerSocket ss = new ServerSocket(10086);
- Socket s = ss.accept();
- String ip = s.getInetAddress().getHostAddress();
- System.out.println(ip+"......connected!");
- InputStream in = s.getInputStream();
- FileOutputStream fos = new FileOutputStream("d:\\321JPG");
- 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();
- ss.close();//服务一次就结束
- }
- }
TCP客户端并发访问
客户端并发访问服务器时,把服务端的处理代码封装在Runnable实现子类的run方法中,并把服务器获的的Socket对象传给该实现子类的构造函数。
服务端通过while循环启动多个线程,对多个客户端请求进行并发处理。这也是一般服务器的基本原理。
- 上传图片(多客户端并发访问)
- import java.io.*;
- import java.net.*;
- /*
- 客户端
- */
- class PicClient
- {
- public static void main(String[] args) throws Exception
- {
- //过滤连接
- //限定java命令传入的参数只能有1个
- if(args.length!=1)//
- {
- System.out.println("请选择一个jpg格式的图片");
- return;
- }
- //判断文件是否是一个存在的文件(不是目录)。
- File file = new File(args[0]);
- if(!(file.exists() && file.isFile()))
- {
- System.out.println("该文件有问题,要么不存在,要么不是文件");
- return;
- }
- //判断这个文件的后缀名是不是.JPG
- if(!file.getName().endsWith(".JPG"))
- {
- System.out.println("图片格式错误,请重新选择");
- return;
- }
- //限定文件大小在5M以内
- if(file.length()>1024*1024*5)
- {
- System.out.println("文件过大,没安好心");
- return;
- }
- Socket s = new Socket("192.168.1.13",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 inLen = in.read(buf);
- System.out.println("Server:"+new String(buf,0,inLen));
- fis.close();
- s.close();
- }
- }
- /*
- 服务端:
- 这个服务端有个局限性,当A客户端连接上以后,被服务端获取到,服务端执行具体流程。
- 这时B客户端连接,只有等待。因为服务端还没有处理完A客户端的请求。还没有循环回来
- 执行下次accept方法。所以,暂时获取不到B客户端对象。那么为了可以让多个客户端
- 同时并发访问服务端。那么服务端最好就是将每个客户端封装到一个单独的线程中去。这
- 样就可以同时处理多个客户端请求。如何定义线程?只要明确了每一个客户端要在服务端
- 执行的代码即可。将该代码存入run方法中。
- */
- 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();
- }
- }
- }
- class PicThread implements Runnable
- {
- private Socket s;
- PicThread(Socket s)
- {
- this.s = s;
- }
- public void run()
- {
- String ip = s.getInetAddress().getHostAddress();
- int count = 0;
- try
- {
- System.out.println(ip+"......connected!");
- InputStream in = s.getInputStream();
- File file = new File(ip+"("+(count)+")"+".JPG");
- while(file.exists())
- file = new File(ip+"("+(count++)+")"+".JPG");//注意new File并不在磁盘上创建文件。
- 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+"上传失败");
- }
- }
- }
示例代码7:客户端并发登陆
最多就登陆三次。
- /*
- 客户端通过键盘录入用户名:
- 服务端对这个用户名进行校验。
- 如果该用户存在,在服务器端显示***,已登录。
- 并在客户端显示:***,欢迎光临。
- 如果该用户不存在,在服务器端显示 ***,尝试登陆
- 并在客户端显示 ***,该用户不存在。
- 最多就登陆三次。
- */
- import java.io.*;
- import java.net.*;
- /*
- 客户端:
- */
- class LoginClient
- {
- public static void main(String[] args) throws Exception
- {
- Socket s = new Socket("192.168.1.13",10010);
- BufferedReader bufr =
- new BufferedReader(new InputStreamReader(System.in));
- PrintWriter out = new PrintWriter(s.getOutputStream(),true);
- BufferedReader in =
- new BufferedReader(new InputStreamReader(s.getInputStream()));
- for(int x =0;x<3;x++)
- {
- String line =bufr.readLine();
- if(line==null)
- break;
- out.println(line);
- String info = in.readLine();
- System.out.println("info:"+info);
- if(info.contains("欢迎"))
- break;
- }
- bufr.close();
- s.close();
- }
- }
- /*
- 服务端:
- */
- class LoginServer
- {
- public static void main(String[] args) throws Exception
- {
- ServerSocket ss = new ServerSocket(10010);
- while(true)
- {
- Socket s = ss.accept();
- new Thread(new LoginThread(s)).start();
- }
- }
- }
- class LoginThread implements Runnable
- {
- private Socket s;
- LoginThread(Socket s)
- {
- this.s = s;
- }
- public void run()
- {
- String ip =s.getInetAddress().getHostAddress();
- System.out.println(ip+".....connected");
- try
- {
- for(int x =0;x<3;x++)
- {
- BufferedReader in =
- new BufferedReader(new InputStreamReader(s.getInputStream()));
- String name = in.readLine();
- if(name==null)
- break;
- BufferedReader bufr =
- new BufferedReader(new FileReader("user.txt"));
- PrintWriter out = new PrintWriter(s.getOutputStream(),true);
- boolean flag = false;
- String line =null;
- while((line=bufr.readLine())!=null)
- {
- if(line.equals(name))
- {
- flag = true;
- break;
- }
- }
- if(flag)
- {
- System.out.println(name+"已登录");
- out.println(name+",欢迎光临");
- break;
- }
- else
- {
- System.out.println(name+",尝试登录");
- out.println(name+",用户名不存在");
- }
- }
- s.close();
- }
- catch (Exception e)
- {
- throw new RuntimeException(ip+":校验失败");
- }
- }
- }
浏览器客户端与自定义服务器
浏览器也是一个客户端,它可以对HTML进行解析。
Dos下的telnet是window提供的远程登陆客户端,命令“telnet ip 地址 口号”可以用连接到网络上的任意一台主机。
Tomcat服务器:默认使用的是8080端口,启动Tomcat服务器,在浏览器是输入“本地地址:8080”就可以看到Tomcat的主页。
- /*
- 演示客户端和服务端。
- 1.客户端:浏览器。
- 服务端:自定义
- 2.
- 客户端是浏览器
- 服务端:TomCat服务器。
- 3.
- 客户端:自定义
- 服务器:TomCat服务器。
- */
- import java.net.*;
- import java.io.*;
- class ServerDemo
- {
- public static void main(String[] args) throws Exception
- {
- ServerSocket ss = new ServerSocket(11000);
- Socket s = ss.accept();
- String ip = s.getInetAddress().getHostAddress();
- System.out.println(ip+"....connected");
- InputStream in = s.getInputStream();
- byte[] buf = new byte[1024];
- int len = in.read(buf);
- System.out.println(new String(buf,0,len));
- PrintWriter out = new PrintWriter(s.getOutputStream(),true);
- out.println("<font color ='red' size = '10'>客户端你好");
- s.close();
- ss.close();
- }
- }
- import java.io.*;
- import java.net.*;
- class MyIE
- {
- public static void main(String[] args) throws Exception
- {
- //浏览器内部建立Socket客户端
- Socket s = new Socket("192.168.1.13",8080);
- //想服务器发送请求消息头
- PrintWriter out = new PrintWriter(s.getOutputStream(),true);//别忘了加true
- out.println("GET /myweb/demo.html HTTP/1.1");
- out.println("Accept: */*");
- out.println("Accept-Language: zh-cn");
- out.println("Host: 192.168.1.13:11000");
- out.println("Connection: Keep-Closed");
- out.println();
- out.println();//请求消息头末尾一定要有一行空行。
- System.out.println("over1");
- //读取服务器发送过来的响应消息头和数据体。
- BufferedReader bufr =
- new BufferedReader(new InputStreamReader(s.getInputStream()));
- String line = null;
- while((line=bufr.readLine())!=null)
- {
- System.out.println(line);
- }
- s.close();
- }
- }
- /*
- http://192.168.1.13:11000/myweb/demo.html
- 客户端http请求消息头,
- /*GET / HTTP/1.1
- Accept: text/html, application/xhtml+xml,
- Accept-Language: zh-CN
- User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)
- Accept-Encoding: gzip, deflate
- Host: 192.168.12.101:10086
- Connection: Keep-Alive
- */
- /*
- 服务器:HTTP响应消息头
- HTTP/1.1 200 OK
- Server: Apache-Coyote/1.1
- Accept-Ranges: bytes
- ETag: W/"315-1358328614234"
- Last-Modified: Wed, 16 Jan 2013 09:30:14 GMT
- Content-Type: text/html
- Content-Length: 315
- Date: Wed, 16 Jan 2013 10:03:30 GMT
URL
URL-:代表一个统一资源定位符,它是指向互联网“资源”的指针。资源可以是简单的文件或目录,也可以是对更为复杂的对象的引用,例如对数据库或搜索引擎的查询。
URI 是统一资源标识符,而 URL是统一资源定位符。因此,笼统地说,每个 URL都是 URI,但不一定每个 URI都是 URL。这是因为 URI还包括一个子类,即统一资源名称 (URN),它命名资源但不指定如何定位资源。
常用方法示例:
intgetDefaultPort() :获取与此 URL关联协议的默认端口号。
String getFile() :获取此 URL的文件名。
String getHost() :获取此 URL的主机名(如果适用)。
String getPath() :获取此 URL的路径部分。
int getPort() :获取此 URL的端口号。
String getProtocol():获取此 URL的协议名称。
String getQuery() :获取此 URL的查询部分。
- import java.net.*;
- class URLDemo
- {
- public static void main(String[] args) throws Exception
- {
- //URL url=new URL("http://192.168.1.13:11000/myweb/demo.html");
- URL url=new URL("http://192.168.1.13:11000/myweb/demo.html?name=haha&age=30");
- System.out.println("getProtocol():"+url.getProtocol()); //http
- System.out.println("getHost():"+url.getHost());//192.168.1.13
- System.out.println("getDefaultPort():"+url.getDefaultPort());//80,如果关联的协议没有默认的端口,则值为-1;
- System.out.println("getPort():"+url.getPort()); // 11000,如果没有设置则为-1;
- System.out.println("getPath():"+url.getPath());// /myweb/demo.html
- System.out.println("getFile():"+url.getFile());///myweb/demo.html?name=haha&age=30
- System.out.println("getQuery():"+url.getQuery());//name=haha&age=30
- /* int port = url.getPort();
- if(port==-1)
- port =80;
- getPort() = -1
- */
- }
- }
域名解析
用Ip地址登陆网站是,不好记忆,人们习惯用主机名。从主机名到获得该主机名对应的Ip地址的过程,就是域名解析。域名解析一般是DNS服务器完成的。
域名解析主要分为两步:
第一步:查找本地的Ip地址和主机名映射表。
这个表,在C:\Windows\System32\drivers\etc文件夹中的hosts文件。127.0.01和localhost的对应关系就在这个表中。
对hosts文件进行设置可以实现一些功能,比如:破解,将软件的官网地址域名与127.0.0.1对应;过滤垃圾网站、恶意网站。
第二步:如果第一步没有找到,那么就去你设置的DNS服务器中去查找映射表,找到对应的IP地址。获得IP地址后,再与之连接。
------------android培训、java培训、期待与您交流! -------------
谁想学java我这有视频,最近几个月一直在看java基础知识,是传智与CSDN合作推出的视频
打开链接点上方的进入黑马学科,老师讲课很幽默,深入浅出、容易理解
点击打开链接 java全套视频
点击打开链接 全世界最适合0基础学习编程的网上校园
点击打开链接 .Net全套视频
点击打开链接 PHP全套视频