您的位置:首页 > 理论基础 > 计算机网络

黑马程序员——网络编程

2015-12-27 11:08 465 查看

-------
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那么启动的时候就找不到其网址,不能进行验证
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息