黑马程序员——网络编程

来源:互联网 发布:网络测试好学吗 编辑:程序博客网 时间:2024/06/06 07:33

------- android培训、java培训、期待与您交流! ----------

网络编程

网络通讯步骤:

1.      找到IP

2.      找到指定端口

3.      找到通讯规则,协议

我做的app没法通过数据连接上网的原因是,我的IP地址是局域网的IP,不是公网的IP,所以没法用,不是公网分给我的IP

常见的端口:

Web服务80

tomcat服务器8080

mysql,3306

常见协议:TCP 和UDP

一、网络模型

OSI参考模型 : 应用层,表示层,会话层,传输层,网络层,数据链路层,物理层

TCP/IP参考模型:应用层(HTTP/FTP),传输层(TCP,UDP),网际层(IP),主机至网络层

二、网络通讯要素:

IP地址:
         网络中设备的标识
         本地回环地址:127.0.0.1默认localhost

//获取主机名

InetAddress i=InetAddress.getLocalHost();

      System.out.println(i.toString());

      System.out.println(i.getHostAddress());

      System.out.println(i.getHostName());

获取任意一台主机IP地址InetAddress

InetAddress is=InetAddress.getByName("www.baidu.com");

      System.out.println(is.getHostAddress());

返回的IP对象可能不唯一,有可能返回一个数组

   端口号:用于标识进程的逻辑地址,不同进程的标识

   有效端口:0-65535,其中0-1024保留端口

   传输协议:TCP,UDP(udp必须会)

udp面向无连接的,不可靠,速度快每个数据包的大小在64k内。

聊天,视频会议等都是UDP

TCP建立连接,在连接中传输数据,通过三次握手连接,可靠,效率低,必须建立连接

三、      TCP传输:

tcp分客户端和服务端,客户端对应的是Socket,服务端对应的是ServerSocket

客户端,在对象建立时就可以连接主机,所以在客户端建立时就要有服务端存在

步骤:

//创建客户端的socket服务,指定主机和端口号

      Socket s=new Socket("192.168.0.105",10005);

      //获取socket中的输出流,写数据到服务端

       OutputStreamos=s.getOutputStream();

       os.write("ge lai le".getBytes());

       os.close();

服务端:

1.  建立服务端的serversocket,并监听一个端口

2.      获取连接过来的客户端对象,通过accept方法,这个方法是阻塞式的,没有连接就会等

3.      客户端如果发过来数据,服务端要使用对应 的客户端对象,并获取到该客户端对象的读取流来读取数据,并打印

4.关闭服务端,可以不关
public class Server {

   public static void main(String args[])throws IOException {

      ServerSocket serv = new ServerSocket(10005);

      Socket s = serv.accept();

      InputStream is = s.getInputStream();

      byte[] buf =newbyte[1024];

      int len = is.read(buf);

      String str = new String(buf, 0, len);

      System.out.println(str);

      String s1 = s.getInetAddress().getHostAddress();

      System.out.println(s1);

      s.close();

   }

}

四、      例子

要求客户端给服务端发送文本,服务端把接收到的文本转换为大写输出到客户端

分析:客户端:

源:键盘输入。目的:网络设备,网络输出流

文本数据,可以选择字符流

步骤:1.建立服务

2.获取键盘录入

3.将数据发给服务器

4.服务器返回大写数据

5.关闭资源

客户端:

public class Client {

 

   public static void main(String[] args)throws IOException  {

      Socket so=new Socket("192.168.0.105",10005);

      BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));

      BufferedWriter bufout=new BufferedWriter(new OutputStreamWriter(so.getOutputStream()));

      BufferedReader bufin=new BufferedReader(new InputStreamReader(so.getInputStream()));

      String line=null;

     

      while((line=bufr.readLine())!=null){

         if("over".equals(line))

            break;

      bufout.write(line);

      bufout.newLine();//加一个回车符,方便服务端返回数据

      bufout.flush();//如果不刷新,就把数据写不过去

      String str=bufin.readLine();

      System.out.println(str);

      }

      bufr.close();

      so.close();

   }

}

服务端:

public class Server {

   public static void main(String args[])throws IOException {

      ServerSocket ss=new ServerSocket(10005);

      Socket so=ss.accept();

      String ip=so.getInetAddress().getHostAddress();

      System.out.println("ip"+ip);

      BufferedReader bufr=new BufferedReader(new InputStreamReader(so.getInputStream()));

//    BufferedWriter bufw=new BufferedWriter(newOutputStreamWriter(so.getOutputStream()));

      PrintWriter pw=new PrintWriter(so.getOutputStream(),true);

      String s=null;

      while((s=bufr.readLine())!=null){//如果没有回车符,那么readline不会返回数据,会继续等待

         /*bufw.write(s.toUpperCase());

         bufw.newLine();

         bufw.flush();*/

         pw.println(s.toUpperCase());

      }

      so.close();

      ss.close();

   }

}

这边出现的问题,两边都有阻塞式方法,readline。如果没有换行标记,那么会一直等待,还有两边都加了缓冲,如果不用flush刷新,那么就会一直在缓冲里面,不会出来,所以既要加换行,又要加刷新

上传文件到服务器:

客户端

//1.读取文件

      //2.把文件写入到服务器

      Socket s=new Socket("192.168.0.105",10005);

      BufferedReader bufr=new BufferedReader(new FileReader("file.txt"));

      PrintWriter pw=new PrintWriter(s.getOutputStream(),true);

      String str=null;

      while((str=bufr.readLine())!=null){

         pw.println(str);

      }

      s.shutdownOutput();

     

      BufferedReader bufin=new BufferedReader(new InputStreamReader(s.getInputStream()));

      String s1=bufin.readLine();

      System.out.println(s1);

      bufin.close();

      s.close();

服务器端:

ServerSocket ss=newServerSocket(10005);

      //1.接收来自客户端的数据

      //2.把接收到的数据存入文件,放入f

      //3.向客户端打印收到数据

      Socket s=ss.accept();

      String s1=s.getInetAddress().getHostAddress();

      System.out.println(s1);

     

      BufferedReader bufr=new BufferedReader(new InputStreamReader(s.getInputStream()));

      BufferedWriter bufw=new BufferedWriter(new FileWriter("f:\\file.txt"));

      String line=null;

      while((line=bufr.readLine())!=null){

         bufw.write(line);

      }

      PrintWriter pw=new PrintWriter(s.getOutputStream(),true);

      pw.println("收到数据");

      s.close();

      bufw.close();

      ss.close();

上传图片

客户端:


//1.把图片读取出来

      //2.把图片写入到服务器

      //3.把流关闭

      Sockets=newSocket("192.168.0.105",10005);

      FileInputStream is=new FileInputStream("d:\\qin1.jpg");

      OutputStream out=s.getOutputStream();

      byte[] b=newbyte[1024];

      int len=0;

      while((len=is.read(b))!=-1){

         out.write(b,0,len);

      }

      s.shutdownOutput();

     

      InputStream in=s.getInputStream();

      int lenth=in.read(b);

      String str=new String(b,0,lenth);

      System.out.println(str);

      s.close();

      is.close();

服务端

ServerSocket ss=newServerSocket(10005);

      Socket socket = ss.accept();

      System.out.println("连接成功");

      InputStream is=socket.getInputStream();

      FileOutputStream out=new FileOutputStream("f:\\1.jpg");

      byte[] b=newbyte[1024];

      int len=0;

      while((len=is.read(b))!=-1){

         out.write(b,0,len);

      }

      OutputStream os=socket.getOutputStream();

      os.write("上传图片成功".getBytes());

      os.close();

      socket.close();

   并发上传图片:

服务端程序:

public class Server {

   public static void main(String args[])throws IOException {

      ServerSocket ss=new ServerSocket(10005);

      while(true){

         Socket socket = ss.accept();

         Date date=new Date();

         System.out.println(date+"连接成功");

         new Thread(new PicThread(socket)).start();

      }

     

   }

}

class PicThreadimplements Runnable{

   Socket socket=null;

   PicThread(Socket s){

      this.socket=s;

   }

 

   @Override

   public void run() {

      InputStream is;

      try {

         is = socket.getInputStream();

         FileOutputStream out=new FileOutputStream("f:\\1.jpg");

         byte[] b=newbyte[1024];

         int len=0;

         while((len=is.read(b))!=-1){

            out.write(b,0,len);

         }

         OutputStream os=socket.getOutputStream();

         os.write("上传图片成功".getBytes());

         os.close();

         socket.close();

      } catch (IOException e) {

         e.printStackTrace();

      }

   }

}

并发登陆

客户端-

Socket so = newSocket("192.168.0.105", 10005);

      InputStream is = System.in;

      BufferedReader bufr = new BufferedReader(new InputStreamReader(is));

      // PrintWriter pw=newPrintWriter(so.getOutputStream(),true);

      BufferedWriter out = new BufferedWriter(new OutputStreamWriter(

            so.getOutputStream()));

      BufferedReader in = new BufferedReader(new InputStreamReader(

            so.getInputStream()));

      for (int i = 0; i < 3; i++) {

         String name = bufr.readLine();

 

         if (name ==null)

            break;

         // pw.println(name);

         out.write(name);

         out.newLine();

         out.flush();

         String line = in.readLine();

         System.out.println(line);

         if (line.contains("欢迎")) {

            break;

         }

      }

      bufr.close();

      so.close();

服务端-

public class Server {

   public static void main(String args[])throws IOException {

      ServerSocket ss = new ServerSocket(10005);

      while (true) {

         Socket socket = ss.accept();

         Date date = new Date();

         System.out.println(date +"连接成功");

         new Thread(new PicThread(socket)).start();

      }

   }

}

 

class PicThreadimplements Runnable {

   Socket socket = null;

 

   PicThread(Socket s) {

      this.socket = s;

   }

 

   @Override

   public void run() {

      InputStream is;

      File file = new File("f:\\user.txt");

      try {

         for (int i = 0; i < 3; i++) {

            BufferedReader in = new BufferedReader(new InputStreamReader(

                   socket.getInputStream()));

            String name = in.readLine();

            BufferedReader bufr = new BufferedReader(new FileReader(file));

            boolean flag =false;

            String line = null;

            while ((line = bufr.readLine()) !=null) {

 

                if (line.equals(name)) {

                   flag = true;

                   break;

                }

            }

            PrintWriter pw = new PrintWriter(socket.getOutputStream(),true);

            if (flag) {

                pw.println("欢迎光临");

                break;

            } else {

                pw.println("用户不存在");

            }

         }

         socket.close();

 

      } catch (Exception e) {

         throw new RuntimeException("校验失败");

      }

   }

}

浏览器也可以作为客户端来访问服务器,在地址栏输入:IP+端口号就可以访问这个应用程序,也可以返回和解析结果

 

如果客户端是浏览器,服务端是tomcat服务器的话也一样。只不过tomcat里面封装了socket

 

 

URL类的用法

URLConnection把Socket封装到里面了,从URLconnection里面获取的数据没有响应头,是属于应用层的对象,而不是传输层的

 

域名解析:比如www.sina.com.cn把主机名翻译成IP地址就需要域名解析,就需要到公网找一台域名解析服务器DNS ,DNS服务器里面都是主机名(新浪)对应的IP地址(www.sina.com.cn)。找到对应的IP地址之后就把IP地址返回给浏览器,浏览器再次发送请求,请求刚才返回来的IP地址,这样才访问到新浪的服务器的

为什么localhost和127.0.0.1对应?

他们的映射关系就在本机上,c:\windows\systems32\drivers\ext\host

补充知识:8080是tomcat的端口,80是web服务器的端口,平时我们不输入80,那么它的返回值是-1,然后再把80赋值给端口号,所以就访问了80了。

当我们访问地址的时候,先去找的本地的主机,然后才找的互联网的DNS服务器,如果在本地配置其它网站的IP-主机名,那么就不走互联网DNS,直接在本地就开始访问IP了,速度比较快,如果不知道主机名的IP地址可以通过如下方法拿到其IP

InewAddress.getByName(“www.sina.com.cn”)

如果myeclipse要收费,把127.0.0.1配置给www.myeclipse.com那么启动的时候就找不到其网址,不能进行验证


0 0
原创粉丝点击