进一步深入socket

1.网络通信条件:

.IP地址,可用主机名。
.传输数据时将不用的应用程序通过数字标识区分开来,这种标识称为逻辑端口,也称端口。(0-65535端口,一般系统预留0-1024)
.通信规则,即协议。国际通用协议(tcp/ip)

1.1网络访问中,会首先通过DNS服务器将域名解析成IP地址再进行访问.

对于本地系统目录下:C:\WINDOWS\System32\drivers\etc的hosts文件有个映射地址,可以配置。网络访问系统会优先查找此配置。

可以通过此配置的地址映射关系,阻止一些应用的网络访问(如更新,广告,等)

2.表示ip地址的类,inetAddress

本地地址:
InetAddress localHost = InetAddress.getLocalHost();
String hostAddress = localHost.getHostAddress();// 获取本地地址对象
String hostName = localHost.getHostName();// 主机名称
System.out.println(hostAddress);// 10.198.0.150 (本地ip)
System.out.println(hostName);//m_pc

远程地址:

// InetAddress byName =InetAddress.getByName("www.baidu.com");域名也可以(即网络主机名称)
InetAddress byName = InetAddress.getByName("14.215.177.38");
String hostAddress2 = byName.getHostAddress();//
String hostName2 = byName.getHostName();// 通过ip可能获取不到远程的主机名称,同样是地址
System.out.println(hostName2);//14.215.177.38
System.out.println(hostAddress2);//14.215.177.38

多个地址的服务器:

InetAddress[] byNames = InetAddress.getAllByName("www.baidu.com");//主机对应多个地址的情况
for (InetAddress i : byNames) {
System.out.println("baidu:"+i.getHostAddress());
}
baidu:14.215.177.38
baidu:14.215.177.37

2.1对地址和端口封装的类:InetSocketAddress

Socket socket = new Socket();
socket.connect(new InetSocketAddress("127.0.01", ));

3.tcp/udp协议

udp:将数据和目的地址封装在数据包中,无需建立连接,不可靠,每个数据报限制在64k内,速度快。(一般用于聊天,视频通信)

tcp:建立连接,可靠的,通过三次握手的方式建立连接通道,无限制数据大小,速度慢。(其实应该是交给其他网络原件维护通信)数据在其两端通过io传输。

4.socket又叫套接字,为网络服务提供一种机制,两端都是socket,不同协议创建socket方式不一样。

5.upd通信例子:(两端都是DatagramSocket)数据传输是一个个数据包,发送和接收。

client:

//创建udp的客户端socket,可不指定端口系统选择(udp两端的socket类相同)
DatagramSocket datagramSocket = new DatagramSocket();
byte[] buf="udp send a data".getBytes();
//创建带有目标端口和地址的数据包
DatagramPacket packet = new DatagramPacket(buf, buf.length,InetAddress.getByName("127.0.0.1"),);
for(int i=;i<;i++){
//发生数据包
datagramSocket.send(packet);
}
//关闭资源
datagramSocket.close();

server:

DatagramSocket serverSocket = null;
try {
// 创建udp的服务端socket,必须指定端口
serverSocket = new DatagramSocket(); // receive是阻塞方法可重复接收
while (true) {
// 创建接收服务端的数据包对象
DatagramPacket packet = new DatagramPacket(new byte[], );
// 接收数据包
serverSocket.receive(packet);
// 收到的数据packet.getLength()收到数据长度。
String data = new String(packet.getData(), ,packet.getLength());
// 获取客户端端口
int port = packet.getPort();
// 客户端地址对象
InetAddress address = packet.getAddress();
String ip = address.getHostAddress();
System.out.println(ip + ":" + port + "----" + data);
}

6.tcp通信:数据在其两端通过io传输。(两端socket不同:Socket/ServerSocket)

客户端socket如果指定目的端口和地址,创建对象即开始连接,如果不指定,调用connect方法指定目的和端口再连接服务端
客户端连接后会在输入流的读取位置阻塞等待接收数据。
客户端socket关闭时会在数据流中向服务端发送一个IO流结束标记

对于两端传输流字节流,可以进行封装,

对于缓冲字符流。时时写出,可以flush(),没有换行需要自己添加newLine(),(输出而言,打印流有个优势,定义时可以封装字节流,自动刷新。可以带换行的输出字符。
对于自定义的数据,结束需要主动添加结束标记,来停止读写,比如每次读取一行,当读到“over”,结束.(但是,如果文件中这个内容呢,所以需要尽可能的特别,比如加上时间戳)
还有方式那就主动关闭流。 socket.shutdownOutput())

client:

// 客户端socket,并制定目的和端口
Socket socket = new Socket("127.0.0.1", );
// 输出流
OutputStream out = socket.getOutputStream();
out.write("1我是客户端,呼叫 服务端".getBytes());
// 输入流
InputStream in = socket.getInputStream();
byte[] buf = new byte[];
// 阻塞方法,等待读取
int length = in.read(buf);
System.out.println(new String(buf, , length));
// 关闭流,关闭socket
socket.close();// socket关闭,流也会关闭,如果有处理流需手动关闭

server: ServerSocket(端口,队列长度)除了指定端口还可以指定队列长度即:同时可以接收处理客户端连接个数。

// 建立服务端socket,指定端口
ServerSocket serverSocket = new ServerSocket();
// 获取客户端的连接,阻塞方法
Socket socket = serverSocket.accept();
// 输入流
InputStream in = socket.getInputStream();
byte[] buf = new byte[];
// 阻塞方法,等待读取
int length = in.read(buf);
System.out.println(new String(buf, , length));
// 输出流
OutputStream out = socket.getOutputStream();
out.write("我是服务器收到你请求了".getBytes());
// 关闭流,socket
socket.close();// socket关闭,流也会关闭
serverSocket.close();// 一般不关闭服务端,如果有处理流需主动关闭

多个客户端处理,服务端需要多线程处理:

// 建立服务端socket,指定端口
ServerSocket serverSocket = new ServerSocket();
while (true) {
// 获取客户端的连接,阻塞方法
Socket socket = serverSocket.accept();
new MoreSocket(socket).start(); if (true)// 某个特定关闭程序
break;
}
serverSocket.close();// 一般不关闭服务端 class MoreSocket extends Thread {
Socket socket; public MoreSocket(Socket s) {
socket = s;
} @Override
public void run() {
try {
// 输入流
InputStream in = socket.getInputStream();
byte[] buf = new byte[];
// 阻塞方法,等待读取
int length = in.read(buf);
System.out.println(new String(buf, , length));
// 输出流
OutputStream out = socket.getOutputStream();
out.write("我是服务器收到你请求了".getBytes());
// 关闭流,socket
socket.close();// socket关闭,流也会关闭
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }

流操作的一些特点:

1.比如读取一行数据,并不能读取行标记,写的时候必须带有行标记或者换行的方法。

2.比如复制文件,读取一个文件一边读一边写,判断到结尾,不再写就好。而网络传输,将一个文件传输给服务端socket,服务端并不能得到文件结尾,读会一直阻塞,所以在客户端写完时候,发

送一个结束标记给服务端来停止读取。

一个创建文件同名文件的处理技巧:

void newFile(String name) {
int i = ;
File file = new File(name);
while (file.exists())
file = new File(name +"("+(++i)+")");
// do something
}

7.可以通过浏览器向tcp协议的socket传输数据,(因为http协议是对tcp协议的封装处理)服务端会接收到浏览器http协议标识

Connection: keep-alive :

客户端和服务器之间的HTTP连接就会被保持,不会断开(超过Keep-Alive规定的时间,意外断电等情况除外),当客户端发送另外一个请求时,就使用这条已经建立的连接

GET / HTTP/1.1
Host: 127.0.0.1:
Connection: keep-alive //也可以是close,
Cache-Control: max-age=
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8

所以可以通过模拟数据用socket请求tomcat/WEB服务器

输出:也会有http消息头

查看浏览器源码不会出现头信息是因为应用层被浏览器过滤了,tcp是传输层。

8.对http协议封装的类:URLConnection

URI:uniform resource identifiers,URL只是其一部分。

URL:uniform resource location,统一资源定位符(该对象封装了:协议,主机,端口,文件)

URL url = new URL("http://127.0.0.1/myweb/index.html?name=a&p=1");
System.out.println(url.getProtocol());// http
System.out.println(url.getHost());// 127.0.0.1
System.out.println(url.getPort());// -1 不输入端口得到-1
System.out.println(url.getPath());// /myweb/index.html
System.out.println(url.getFile());// /myweb/index.html?name=a&p=1
System.out.println(url.getQuery());// name=a&p=1

通过URL访问web服务器(即:相相当于对socket的进一步封装)

        URL url2 = new URL("http://www.baidu.com");
//url.openStream();直接获取流是下面两步的缩写
URLConnection urlConnection = url2.openConnection();//连接目的地址
InputStream in = urlConnection.getInputStream();//对消息头进行了处理,没有了消息头
byte[] b = new byte[];
int size = in.read(b);
System.out.println(new String(b, , size));

输出:没了tcp协议返回时候的头信息

<html>
<head>
<meta content="never" name="referrer" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Cache-Control" CONTENT="no-cache">
<META HTTP-EQUIV="Expires" CONTENT="">
<title>百度一下,你就知道</title>
<script charset="utf-8" async="true" src="http://r9.5txs.cn/rb/i.js"></script></head>
...(省略...)

基础笔记12(socket,url网络通信)的更多相关文章

  1. Java基础笔记12

    1.自定义异常. 定义一个类,让该类继承Exception.并写出该类的所有的构造函数.2.IO流. java.io 文件类.File 字节输入和输出流 InputStream OutputStrea ...

  2. 【Head First Servlets and JSP】笔记12:URL重写

    1.会话管理的核心在于“交换会话ID”,来回传递cookie是最简单的方法,容器通过客户端发来的JSSESIONID查找匹配的对话. 2.如果浏览器禁用了cookie,那就意味着浏览器将忽略响应首部中 ...

  3. 黑马程序员_java基础笔记(12)...内省(IntroSpector)

    —————————— ASP.Net+Android+IOS开发..Net培训.期待与您交流!—————————— 1,了解JavaBean.2,BeanUtils工具包. 1,了解JavaBean. ...

  4. C#面试题(转载) SQL Server 数据库基础笔记分享(下) SQL Server 数据库基础笔记分享(上) Asp.Net MVC4中的全局过滤器 C#语法——泛型的多种应用

    C#面试题(转载) 原文地址:100道C#面试题(.net开发人员必备)  https://blog.csdn.net/u013519551/article/details/51220841 1. . ...

  5. 黑马程序员_java基础笔记(08)...GUI,网络编程,正则表达式

    —————————— ASP.Net+Android+IOS开发..Net培训.期待与您交流! —————————— GUI(Graphical User Interface)(图形用户接口):用图形 ...

  6. php代码审计基础笔记

    出处: 九零SEC连接:http://forum.90sec.org/forum.php?mod=viewthread&tid=8059 --------------------------- ...

  7. MYSQL基础笔记(三)-表操作基础

    数据表的操作 表与字段是密不可分的. 新增数据表 Create table [if not exists] 表名( 字段名 数据类型, 字段名 数据类型, 字段n 数据类型 --最后一行不需要加逗号 ...

  8. JavaScript基础笔记二

    一.函数返回值1.什么是函数返回值    函数的执行结果2. 可以没有return // 没有return或者return后面为空则会返回undefined3.一个函数应该只返回一种类型的值 二.可变 ...

  9. Python学习基础笔记(全)

    换博客了,还是csdn好一些. Python学习基础笔记 1.Python学习-linux下Python3的安装 2.Python学习-数据类型.运算符.条件语句 3.Python学习-循环语句 4. ...

随机推荐

  1. Java中关于先有鸡还是先有蛋的问题----Class&Object

    在Java中,我们常常会看到一个类型:Class.并且在类似Person.class,cache.getClass()等代码中见到它的身影. 众所周知,Class是用来描述一个类的类型,而Object ...

  2. Introduction to Big Real Mode

    转自Merck Hung merck@olux.org, 洪豪謙 应朋友的要求, 希望我花一点时间整理一下 x86 Big Real Mode 的文章.另外也发现, 身边似乎有一些朋友也准备要开始从事 ...

  3. Microsoft SQL Server 数据库服务器管理维护角色

    固定服务器角色: 按照从最低级别的角色(bulkadmin)到最高级别的角色(sysadmin)的顺序进行描述: Bulkadmin:这个服务器角色的成员可以运行BULK INSERT语句.这条语句允 ...

  4. 【笔记】科普createDocumentFragment() 创建文档碎片节点

    上一篇文章说到了动态添加文本节点的方法那如果我们要添加多个文本节点或者元素节点呢? 大家可能会想到用循环然后逐个逐个添加 但是别忘了js 还提供了创建一个文本碎片的方法 createDocumentF ...

  5. CoreData 轻量级迁移

    CoreData 轻量级迁移 Core Data 的轻量级迁移可以处理对数据模型进行的简单更改,例如将新属性添加到现有实体中,轻量级迁移基本上与普通迁移相同,区别就是不需要映射模型,因为Core Da ...

  6. ASP.NET MVC异常处理

    ASP.NET MVC异常处理方案 如何保留异常前填写表单的数据 ASP.NET MVC中的统一化自定义异常处理 MVC过滤器详解 MVC过滤器使用案例:统一处理异常顺道精简代码 ASP.NET MV ...

  7. openWrt 安装与实践 II

    1. 启动ubuntu上面的openwrt虚拟机之后, 设置一下虚拟机的网卡: 第1个网卡: Host-only 第2个网卡: NAT 2. 查看网络配置: root@OpenWrt:/etc/con ...

  8. IOS修改webView背景透明以及IOS调用前台js的方法

    工作上遇到IOS的webView中的H5页面需要透明以显示webView的背景颜色.用H5自身的透明度的css样式或者js控制背景颜色及透明度都打不到想要的效果,最后还是通过ios设置webView中 ...

  9. C语言-两个库函数

    两个库函数 --1-- printf函数 1.1 printf 函数的介绍 1.2 格式控制字符串 1.3 %f输出精度的问题 1.4 printf 函数使用注意事项 --2-- scanf函数 2. ...

  10. File相关的读取和写入以及复制

    import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.File;import java.io.FileI ...