黑马程序员 java基础之网络编程TCP


TCP网络传输。

客户端和服务端

 

分别对应着两个对象。

Scoket(客户端)和ServerSocket(服务端)。

 

  Socket(String  address, int port)

          创建一个流套接字并将其连接到指定 IP 地址的指定端口号。

这个客户端在一建立的情况下就去连接服务端。

通过指定地址和指定的端口找到服务端。并与之建立连接。

 

步骤:
1.创建Socket服务,并指定要连接的主机和端口。

   Socket s = new Socket("localhost",10002);

   如果上述这步成功了的话。也就是通路建立了。

当通路一建立,就有一个Socket流,也就是网络流。

两端之间建立了一个网络流。Socket中既有输入流也有输出流,

一旦建立连接,在Socket中就可以取到输入流和输出流对数据进行操作。

 

流不用去建立,只要通路一建立,流就存在了。

 

getOutputStream()

         返回此套接字的输出流。

getInputStream()

         返回此套接字的输入流。

 

服务端

 

服务端没有自己的流对象。

服务端和客户端连接的时候,就使用了客户端的流对象和客户端进行操作。

 

public classTCPSocket {

 

      /**

       *@param args

       */

      public static void main(String[] args)throws Exception

      {

          

           Socket s = newSocket("localhost",10002);

           //为了发送数据,应该获取socket流中的输出流

           OutputStream os =s.getOutputStream();

          

           BufferedWriter bw = newBufferedWriter(new OutputStreamWriter(os));

 

           bw.write("tcp,gemenwolaile");

           bw.flush();

           //而在这里不同去关流

           s.close();

          

      }

 

}

 

/*

 * 需求:定义端点接收数据并打印在控制台上。

 * 服务端:

 * 1.建立服务端的Socket服务。通过ServerSocket类去建立。

 * 一旦建立,并监听一个端口。

 * 2.获取链接过来的客户端对象。

 *   通过ServerSocket的accept方法去获得。所以这个方法是阻塞式。

 * 3.客户端如果发过来数据,那么服务端要使用对应的客户端对象,并获取到该客户端

 * 的读取流来读取发过来的数据。并打印在控制台。

 * 4.关闭服务端。(可选)

 * 

 * */

class TcpServer

{

      public static void main(String[] args)throws Exception

      {

          

           //建立服务端Socket服务,并监听一个端口。

           ServerSocket ss  = new ServerSocket(10002);

           //通过accept方法获取连接过来的客户端对象。

           Socket s = ss.accept();

          

           System.out.println(s.getInetAddress().getHostAddress());

           //获取客户端发送过来的数据,那么要使用客户端对象的读取流方法来读取数据。

          

           InputStream in = s.getInputStream();

          

           byte[] buf = new byte[1024];

          

           int len = in.read(buf);

          

           System.out.println(newString(buf,0,len));

          

     

           s.close();//关闭客户端。

          

          

          

      }

     

 

}

 

必须先启动服务端。

 

 

 

演示tcp传输的客户端和服务端的互访。

需求:客户端给服务端发送数据,服务端收到后,给客户端反馈信息。

 

/*

 1.建立socket服务。指定要连接的主机和端口

 2.获取socket流中的输出流,将数据写到该流中。通过网络发送给服务端。

 3.获取socket流中的输入流,将服务器反馈的数据获取到,并打印。

 4.关闭客户端资源。

 */

 

class TcpClient2

{

      public static void main(String[] args)throws Exception

      {

           Socket s =  new Socket("localhost",10004);

           OutputStream os = s.getOutputStream();

           os.write("nihao".getBytes());

          

           InputStream is = s.getInputStream();

          

           byte [] arr = new byte[1024];

           //十分要主要,这里的read读的是Socket流。也是一个阻塞式方法。只有服务端往回发送数据的时候,才会解除阻塞。

           int len = is.read(arr);

          

           System.out.println(newString(arr,0,len));

           s.close();

     

          

      }

}

class TcpServer2

{

      public static void main(String[] args)throws Exception

      {

           ServerSocket ss = newServerSocket(10004);

          

           Socket s = ss.accept();

           InputStream is = s.getInputStream();

          

           byte [] arr = new byte[1024];

           int len = is.read(arr);

          

           System.out.println(newString(arr,0,len));

          

           OutputStream os =s.getOutputStream();

           os.write("完成".getBytes());

          

           s.close();

          

          

          

          

      }

}

 

 

 

 

package day5;

importjava.net.*;

importjava.io.*;

public classTCPSocket2 {

 

     

      public static void main(String[] args) {

           // TODO Auto-generated method stub

 

      }

 

}

 

 

class Client3

{

 

      public static void main(String[] args)throws Exception

      {

           Socket s = newSocket("localhost",10009);

          

           BufferedWriter bw = new BufferedWriter(newOutputStreamWriter(s.getOutputStream()));

          

           BufferedReader br = newBufferedReader(new InputStreamReader(System.in));

           String ss = null;

          

           BufferedReader brr = newBufferedReader(new InputStreamReader(s.getInputStream()));

           while((ss = br.readLine())!=null)

           {

                 bw.write(ss);

                 bw.newLine();

                 bw.flush();

                

           System.out.println(brr.readLine());

     

           }

          

          

           br.close();

           s.close();

          

                

          

      }

}

class Server3

{

 

      public static void main(String[] args)throws Exception

      {

           ServerSocket ss = newServerSocket(10009);

          

           Socket s = ss.accept();

           InputStream is = s.getInputStream();

          

           BufferedReader br = newBufferedReader(new InputStreamReader(is));

          

           OutputStream os =s.getOutputStream();

           BufferedWriter bw = new BufferedWriter(newOutputStreamWriter(os));

           String sss  = null;

           while((sss = br.readLine())!=null)

           {

                 //上边的readLine只有在看到回车符后才能结束,也就是解除阻塞。

          

                

          

           bw.write(sss.toUpperCase());

           bw.newLine();

           bw.flush();

           }

          

           //有一个疑问,为什么当客户端结束的时候,服务端也结束了,

           //这是因为,当客户端调用s.close()时,会在流里写一个-1,

           //然后服务器端就跳出循环,然后通过ss关闭服务器。

           ss.close();

          

          

          

          

      }

}

 

要注意,对于读取流中的阻塞式方法来说,一定要将发送发的缓冲区刷新。

而且必须将行结束符写到这个流中。

 

对于服务器端的阻塞式方法,如readLine(),必须在客户端发送一个标志,让服务器端知道其结束了,否则服务器一直处于读取数据的状态。

在客户端使用

s.shutdownOutput();//关闭客户端的输出流,相当于给流中加入一个结束标记

 

 

下边,我们使用更高级的协议去完成一个自定义浏览器和tomcat服务器的处理请求。

可以直接使用应用层的协议去封装。

URL url = newURL("http://localhost:8080/GP2/index.jsp");

//首先将url地址封装到一个对象为URL中。

URLConnectionconn = url.openConnection();

//这个URLConnection就封装了有关底层协议的一些信息。

//也就通过一些应用层的协议进行拆包,并将这些属性封装到这个对象中去.

//然后通过openConnection()在内部帮助我们去完成Socket等一系列连接动作。

//所以不同写Socket(是在传输层上的协议),而且是带着协议去封装的。

 

 

//当连接成功,当然可以将其服务端传递过来的数据拿到。也就是得到输入流对象。

从获取值

InputStream is =conn.getInputStream();

 

//从而从这个流对象中的得到值

byte [] arr =new byte[1024];

          

           int len = 0;

           while((len = is.read(arr))!=-1)

           {

                 System.out.println(newString(arr,0,len));

                

           }

 

这时候传递过来的数据就没有了响应头。而直接打出html中的信息。

这是因为。当底层的网络协议把数据封装好之后(包括响应头),通过应用层去拆包之后,将数据和响应头分离开来,得到的数据就只剩数据了。

而这些响应头中的信息,可以通过URLConnection对象中的一系列方法进行简析.

比如说:System.out.println(conn.getHeaderField("Server"));

可以得到有关服务器的信息。

当浏览器写入一个网址之后,去访问某一台主机的时候.它到底做什么了事情?

 在上网的时候,先去本地找hosts中的各自域名的映射关系.

当本地有,就返回本地的,如localhost,如果本地没有,就去各自运营商提供的域名服务器DNS中去寻找映射关系,最后使用ip地址找到对应的服务器,使用端口找到对应的应用程序.如果直接输入ip地址,则不走域名简析.

 

 

 

转载于:https://www.cnblogs.com/xiewen3410/archive/2013/05/14/3078647.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/408864.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[GAN学习系列] 初始GAN

本文大约 3800 字,阅读大约需要 8 分钟要说最近几年在深度学习领域最火的莫过于生成对抗网络,即 Generative Adversarial Networks(GANs)了。它是 Ian Goodfellow 在 2014 年发表的,也是这四年来出现的各种 GAN 的变种的开山鼻祖了&#xff0…

linux 端口 established,ubuntu/linux上查看端口使用情况

想查看TCP或者UDP端口使用情况,使用netstat -anp如果有些进程看不见,如只显示”-”,可以尝试sudo netstat -anp如果想看某个端口的信息,使用lsof命令,如:sudo lsof -i :631-bash-3.00# netstat -tlnnetstat…

[资源分享] 吴恩达最新《机器学习训练秘籍》中文版可以免费下载了

本文大约 600 字, 阅读大约需要 2 分钟 吴恩达老师在上个月底宣布终于完成了他最新的书籍《Machine Learning Yearning》的最后几个章节: 而最近这本书也有了免费的完整中文版下载了,中文版的名称是《机器学习训练秘籍》,封面如下…

linux一g运行内存不足,在linux运行weblogic出现运行内存不足错误,求鞭挞....

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼# There is insufficient memory for the Java Runtime Environment to continue.# Native memory allocation (malloc) failed to allocate 1431830528 bytes for committing reserved memory.# An error report file with more i…

Android学习笔记44:JSON数据解析

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,为Web应用开发提供了一种理想的数据交换格式。 本文将主要介绍在Android开发中,如何在服务器端创建JSON数据,以…

[GAN学习系列2] GAN的起源

本文大约 5000 字,阅读大约需要 10 分钟 这是 GAN 学习系列的第二篇文章,这篇文章将开始介绍 GAN 的起源之作,鼻祖,也就是 Ian Goodfellow 在 2014 年发表在 ICLR 的论文–Generative Adversarial Networks”,当然由于…

两条路,此人如何问甲乙问题?才能走向京城

描述: 有甲、乙两人,其中,甲只说假话,而不说真话;乙则是只说真话,不说假话。但是,他们两个人在回答别人的问题时,只通过点头与摇头来表示,不讲话。有一天,一个…

[资源分享] Github上八千Star的深度学习500问教程

本文大约 600 字,阅读大约需要 2 分钟这周要分享的一个资源是来自 Github 上的已经有八千多 Star 的一个深度学习知识总结,如下图所示:其 Github 地址为:https://github.com/scutan90/DeepLearning-500-questions它目前是有 16 个…

获取android系统手机的铃声和音量

获取android系统手机的铃声和音量 通过程序 获取android系统手机的铃声和音量。设置音量的方法也很简单,AudioManager提供了方法: publicvoidsetStreamVolume(intstreamType,intIndex,intFlags)其中streamType有内置的常量,去文档里面就可以…

linux的xmgrace无法运行,科学网—安装xmgrace - 林绪波的博文

安装xmgrace如果不接触GROMACS我不会知道有一个类似于origin的LINUX下作图的软件――xmgrace下载地址(可自行搜索)http://plasma-gate.weizmann.ac.il/Grace/安装过程:# tar xvzf grace-5.1.20.tar.gz# cd grace-5.1.20.# ./configure# make# make install以上的解压…

谷歌开源的 GAN 库--TFGAN

本文大约 8000 字,阅读大约需要 12 分钟 第一次翻译,限于英语水平,可能不少地方翻译不准确,请见谅! 最近谷歌开源了一个基于 TensorFlow 的库–TFGAN,方便开发者快速上手 GAN 的训练,其 Github …

h3c交换机配置文件的导出

首先要知道一个命令 就是进入 系统视图 system-view 然后 dir 查看 交换机 flash里的所有文件。 一、使用TFTP方式 步骤1、在PC机“开始菜单”的“运行”栏中键入“cmd”,进入DOS界面,保证PC机可以PING通设备。 步骤2、在PC机上安装TFTP服务器端软…

linux快速php,Linux 下的这些高效指令,是你快速学习的神器

linux是一套免费使用和自由传播的类unix操作系统,是一个基于posix和unix的多用户、多任务、支持多线程和多cpu的操作系统。它能运行主要的unix工具软件、应用程序和网络协议。它支持32位和64位硬件。linux继承了unix以网络为核心的设计思想,是一个性能稳…

TensorFlow 加载多个模型的方法

采用 TensorFlow 的时候,有时候我们需要加载的不止是一个模型,那么如何加载多个模型呢? 原文:https://bretahajek.com/2017/04/importing-multiple-tensorflow-models-graphs/ 关于 TensorFlow 可以有很多东西可以说。但这次我只…