Day19 网络编程
基本概念
网络:一组由网线连接起来的计算机。
网络的作用:
1.信息共享。
2.信息传输。
3.分布式处理。
4.综合性的处理。
internet:互联网
Internet:是互联网中最大的一个。
www:万维网,web,是Internet因特网的一个服务。
协议
IP:网际传输协议。传输数据,不保证数据的准确性。
TCP:传输控制协议,可以确保数据的准确性。
HTTP(超文本传输协议):超文本
FTP(文件传输协议):文件传输协议
SMTP(简单邮件传输协议):邮件的传输。
IP地址:网络上通信实体的标识。
IP地址分类
A:0.0.0.0 - 127.255.255.255,其中0和127不可用
B:128.0.0.0 - 191.255.255.255
C:192.0.0.0 - 223.255.255.255
D:224.0.0.0 - 239.255.255.255
E:240.0.0.0 - 255.255.255.255,其中段255不可用
服务端口:计算机通过不同的服务端口来区分不同网络服务,就像通过进程号区分不同的进程一样;常见服务的端口,HTTP(80),FTP(21)
OSI与TCP/IP体系模型
网络体系结构解决异质性问题采用的是分层的方法——把复杂的网络互联问题划分为若干个较小的、单一的问题,在不同层上予以解决。
OSI(Open System Interconnection)参考模型将网络的不同功能划分为7层:
应用层:处理网络应用
表示层:数据表示
会话层:主机间通信
传输层:端到端的连接
网络层:寻址和最短路径
数据链路层:介质访问(接入)
物理层:二进制传输
通信实体的对等层之间不允许直接通信,各层之间是严格的单向依赖,上层(Service user)使用下层提供的服务,下层(Service provider)向上层提供服务。
对等层通信的实质:对等层实体之间虚拟通信,下层向上层提供服务,实际通信在最底层完成。
OSI各层所使用的协议
应用层:Telnet、FTP、HTTP、DNS、SMTP、POP3
传输层:TCP、UDP
TCP:面向连接的可靠的传输协议。
UDP:是无连接的,不可靠的传输协议。
网络层:IP、ICMP、IGMP
TCP
TCP是Transfer Control Protocol(传输控制协议)的简称,是一种面向连接的保证可靠传输的协议。
在TCP/IP协议中,
IP层主要负责网络主机的定位,数据传输的路由,由IP地址可以唯一确定Internet上的一台主机。
而TCP层则提供面向应用的可靠的或非可靠的数据传输机制,这是网络编程的主要对象,一般不需要关心IP层是如何处理数据的。
通过TCP协议传输,得到的是一个顺序的无差错的数据流。
发送方和接收方的成对的两个socket之间必须建立连接,以便在TCP协议的基础上进行通信。
当一个socket(通常都是server socket)等待建立连接时,另一个socket可以要求进行连接,一旦这两个socket连接起来,它们就可以进行双向数据传输,双方都可以进行发送或接收操作。
TCP是一个基于连接的协议,它能够提供两台计算机之间的可靠的数据流。
HTTP、FTP、Telnet等应用都需要这种可靠的通信通道。
UDP
UDP是User Datagram Protocol的简称,是一种无连接的协议。
UDP是从一台计算机向另一台计算机发送称为数据报的独立数据包的协议,该协议并不保证数据报是否能正确地到达目的地,它是一个非面向连接的协议。
每个数据报都是一个独立的信息,包括完整的源地址或目的地址,它在网络上以任何可能的路径传往目的地,因此能否到达目的地,到达时间以及内容的正确性都是不能保证的。
TCP和UDP的比较
使用UDP时,每个数据报中都给出了完整的地址信息,因此无需建立发送方和接收方的连接。
对于TCP协议,由于它是一个面向连接的协议,在socket之间进行数据传输之前必然要建立连接,所以在TCP中多了一个连接建立的时间。
使用UDP传输数据时是有大小限制的,每个被传输的数据报必须限定在64KB之内。
TCP没有这方面的限制,一旦连接建立起来,双方的socket就可以按统一的格式传输大量的数据。
UDP是一个不可靠的协议,发送方所发送的数据报并不一定以相同的次序到达接收方。
TCP是一个可靠的协议,它确保接收方完全正确地获取发送方所发送的全部数据。
可靠的传输是要付出代价的,对数据内容正确性的检验必然占用计算机的处理时间和网络的带宽。因此TCP传输的效率不如UDP高。
TCP在网路通信上有极强的生命力,例如远程连接(Telnet)和文件传输(FTP)都需要不定长度的数据被可靠地传输。
相比之下UDP操作简单,而且仅需要较少的监护,因此通常用于局域网高可靠性的分散系统中client/server应用程序。
TCP/IP与OSI参考模型的对应关系
URL
统一资源定位符。
格式
protocol://hostname[:port]/path/[?query]#fragment
协议 ://主机名或IP:端口/路径?字符串=值&字符串=值#片段
常用方法
getProtocol():获得协议名称
getHost():获得主机名称或IP
getPort():获得端口
getDefaultPort():获得默认端口
getQuery():获得查询串
getRef():获得片段
getPath():获得路径
getFile():获得路径和查询串
public class TestURL { public static void main(String[] args) throws MalformedURLException {
// URL
URL url = new URL("http://127.0.0.1:8080/data/a.txt?id=1&page=2#hello");
System.out.println(url.getProtocol());//协议
System.out.println(url.getHost());//主机
System.out.println(url.getPort());//端口
System.out.println(url.getDefaultPort());//默认端口
System.out.println(url.getPath());//路径
System.out.println(url.getFile());//路径 和 查询串
System.out.println(url.getQuery());//查询串
System.out.println(url.getRef());//片段
} }
URL资源下载
openStream()
public class TestURL1 { public static void main(String[] args) throws IOException {
// URL-openStram()资源下载
URL url = new URL("http://img15.3lian.com/2016/h1/233/d/156.jpg");
//获得了 URL的定位资源得 输入流
InputStream in = url.openStream();
OutputStream out = new FileOutputStream("d:/data/datou.jpg");
int temp;
while((temp = in.read())!= -) {
out.write(temp);
}
in.close();
out.close();
} }
InetAddress类
常用方法
getLocalHost():获得本机地址
getByName(String host):通过主机名或IP地址获得一个InetAddress的一个封装
getHostName():获得主机名称
getHostAddress():获得主机地址
public class TestInetAddress { public static void main(String[] args) throws UnknownHostException {
// InetAddress
//获得 本机的IP
System.out.println(InetAddress.getLocalHost());
//通过 主机名 后 IP地址 获得一个 InetAddress的一个封装
InetAddress i = InetAddress.getByName("www.baidu.com");
//单独 获得 主机的 IP地址
System.out.println(i.getHostAddress());
//主机的名称
System.out.println(i.getHostName());
} }
Socket
Socket通讯
网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket。Socket通常用来实现客户方和服务方的连接。Socket是TCP/IP协议的一个十分流行的编程界面,一个Socket由一个IP地址和一个端口号唯一确定。
在传统的UNIX环境下可以操作TCP/IP协议的接口不止Socket一个,Socket所支持的协议种类也不光TCP/IP一种,因此两者之间是没有必然联系的。在Java环境下,Socket编程主要是指基于TCP/IP协议的网络编程。
使用Socket进行网络通信的过程
服务器程序将一个套接字绑定到一个特定的端口,并通过此套接字等待和监听客户的连接请求。
客户程序根据服务器程序所在的主机名和端口号发出连接请求。
如果一切正常,服务器接受连接请求。并获得一个新的绑定到不同端口地址的套接字。(不可能有两个程序同时占用一个端口)。
客户和服务器通过读写套接字进行通讯。
使用ServerSocket和Socket实现服务器端和客户端的Socket通信。
其中:
左边ServerSocket类的构造方法可以传入一个端口值来构建对象。
accept()方法监听向这个socket的连接并接收连接。它将会阻塞直到连接被建立好。连接建立好后它会返回一个Socket对象。
连接建立好后,服务器端和客户端的输入流和输出流就互为彼此,即一端的输出流是另一端的输入流。
对于一个功能齐全的Socket,都要包含以下基本结构,其工作过程包含以下四个基本的步骤:
(1) 创建Socket;
(2) 打开连接到Socket的输入/出流;
(3) 按照一定的协议对Socket进行读/写操作;
(4) 关闭Socket.
Socket通信程序测试
server端
package day19.socket1; import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner; //服务器 1.0
public class Server { public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(); //等待客户端连接,连接成功分配一个 Socket
Socket socket = server.accept();
//
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
//
Scanner in = new Scanner(is);
PrintWriter out = new PrintWriter(os,true);//刷新
//写
out.println("客户端你连接成功了!");
out.println("end");//
//读
String sr;
while(true) {
sr = in.nextLine();
System.out.println("客户端说了:"+sr);
if(sr.equals("end")) {
break;
}
}
//关
socket.close();//客户端
} }
client端
package day19.socket1; import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner; //客户端
public class Client { public static void main(String[] args) throws UnknownHostException, IOException {
// 要访问的服务器 的IP地址,和端口
Socket socket = new Socket(InetAddress.getLocalHost(), );
//获得 Socket流
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
//包装
Scanner in = new Scanner(is);
// true 自动刷新缓冲区
PrintWriter out = new PrintWriter(os,true);
//读
String sr,sw;
while(true) {
sr = in.nextLine();//读服务器传过来的一行信息
System.out.println("服务器说了:"+sr);
if(sr.equals("end")) {
break;
}
}
//写
Scanner input = new Scanner(System.in);
while(true) {
System.out.print("客户端输入信息:");
sw = input.next();
//写
out.println(sw);
if(sw.equals("end")) {
break;
}
}
//关
socket.close(); } }
然后先运行服务器端,再运行客户端,可以看到,运行客户端之后输出服务器端的后续代码。
表明连接建立后才会往下执行。
使用多线程实现简单聊天
server端
package day19.socket5; import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner; /**
* 服务器
* @version 5.0
*/
public class TestServer {
public static void main(String[] args) throws IOException {
@SuppressWarnings("resource")
ServerSocket server = new ServerSocket();
//分配客户端
Socket socket = server.accept();
//流
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
//包装
Scanner in = new Scanner(is);
PrintWriter pw = new PrintWriter(os, true);
System.out.println("----------------服务器----------------------");
//写
pw.println("--客户端连接服务器成功--");
SSWrite w = new SSWrite(pw,socket);
Thread tssw = new Thread(w,"服务器-写-线程");
tssw.start();
//读
SSRead r = new SSRead(in);
Thread tssr = new Thread(r,"服务器-读-线程");
tssr.start();
}
}
//读线程
class SSRead implements Runnable{
Scanner in;
public SSRead(Scanner in) {
this.in = in;
}
@Override
public void run() {
String sr;
while (in.hasNext()) {
sr = in.nextLine();
System.out.println("来自客户端的消息:"+sr);
if (sr.equals("end")) {
break;
}
}
}
}
//写线程
class SSWrite implements Runnable{
PrintWriter pw;
Socket socket;
public SSWrite(PrintWriter pw,Socket socket) {
this.pw = pw;
this.socket = socket;
}
@Override
public void run() {
String sw;
Scanner input = new Scanner(System.in);
while (input.hasNextLine()) {
sw = input.nextLine();
pw.println(sw);
if (sw.equals("end")) {
try {
socket.close();//关闭
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
}
}
client端
package day19.socket5; import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
/**
* 客户端
* @version 5.0
*/
public class Client { public static void main(String[] args) throws UnknownHostException, IOException { // 服务器IP地址,端口号
Socket socket = new Socket(InetAddress.getLocalHost(), ); //和服务器聊天
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
//包装
Scanner in = new Scanner(is);
PrintWriter pw = new PrintWriter(os);
System.out.println("----------------客户端-----------------------");
//读写操作
//读
Read r = new Read(in);
Thread tr = new Thread(r,"读-线程");
tr.start();
//写
Write w = new Write(pw,socket);
Thread tw = new Thread(w,"写-线程");
tw.start();
//关闭流
// s.close();
}
}
//读线程
class Read implements Runnable{
Scanner in;
public Read(Scanner in) {
this.in = in;
}
@Override
public void run() {
String sr;
while (in.hasNext()) {
sr = in.nextLine();
System.out.println("来自服务器的消息:"+sr);
if (sr.equals("end")) {
break;
}
}
in.close();
}
}
//写线程
class Write implements Runnable{
PrintWriter pw;
Socket socket;
public Write(PrintWriter pw,Socket socket) {
this.pw = pw;
this.socket = socket;//关闭客户端
}
@Override
public void run() {
String sw;
Scanner input = new Scanner(System.in);
while (input.hasNextLine()) {
sw = input.nextLine();
pw.println(sw);
pw.flush();
if (sw.equals("end")) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}//
break;
}
}
}
}
UDP简单使用
server端
package day19.udp1; import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException; public class UServer { public static void main(String[] args) throws IOException {
// 接收方 9999
byte [] b = new byte[];
//打包
DatagramPacket dp = new DatagramPacket(b, b.length);
//接收方
DatagramSocket ds = new DatagramSocket();
//接收
ds.receive(dp);
byte [] bt = dp.getData();
System.out.println(new String(bt,"gbk"));
ds.close();
} }
client端
package day19.udp1; import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Scanner; public class UClient { public static void main(String[] args) throws IOException {
// 发送方
Scanner input = new Scanner(System.in);
System.out.println("输入要传输的数据:");
String s = input.next();
//
byte [] b = s.getBytes();
//打包 接收方的端口
DatagramPacket dp = new DatagramPacket(b,b.length,InetAddress.getLocalHost(),);
//发送 发送方的端口
DatagramSocket ds = new DatagramSocket();
ds.send(dp);
//
ds.close();
} }
Day19 网络编程的更多相关文章
- 猫哥网络编程系列:HTTP PEM 万能调试法
注:本文内容较长且细节较多,建议先收藏再阅读,原文将在 Github 上维护与更新. 在 HTTP 接口开发与调试过程中,我们经常遇到以下类似的问题: 为什么本地环境接口可以调用成功,但放到手机上就跑 ...
- python select网络编程详细介绍
刚看了反应堆模式的原理,特意复习了socket编程,本文主要介绍python的基本socket使用和select使用,主要用于了解socket通信过程 一.socket模块 socket - Low- ...
- Linux Socket 网络编程
Linux下的网络编程指的是socket套接字编程,入门比较简单.在学校里学过一些皮毛,平时就是自学玩,没有见识过真正的socket编程大程序,比较遗憾.总感觉每次看的时候都有收获,但是每次看完了之后 ...
- 猫哥网络编程系列:详解 BAT 面试题
从产品上线前的接口开发和调试,到上线后的 bug 定位.性能优化,网络编程知识贯穿着一个互联网产品的整个生命周期.不论你是前后端的开发岗位,还是 SQA.运维等其他技术岗位,掌握网络编程知识均是岗位的 ...
- 浅谈C#网络编程(一)
阅读目录: 基础 Socket编程 多线程并发 阻塞式同步IO 基础 在现今软件开发中,网络编程是非常重要的一部分,本文简要介绍下网络编程的概念和实践. Socket是一种网络编程接口,它是对传输层T ...
- C++11网络编程
Handy是一个简洁优雅的C++11网络库,适用于linux与Mac平台.十行代码即可完成一个完整的网络服务器. 下面是echo服务器的代码: #include <handy/handy.h&g ...
- Java - 网络编程
Java的网络编程学习,关于计算机基础的学习参考:计算机网络基础学习 - sqh. 参考:
- Linux网络编程-IO复用技术
IO复用是Linux中的IO模型之一,IO复用就是进程预先告诉内核需要监视的IO条件,使得内核一旦发现进程指定的一个或多个IO条件就绪,就通过进程进程处理,从而不会在单个IO上阻塞了.Linux中,提 ...
- Python Socket 网络编程
Socket 是进程间通信的一种方式,它与其他进程间通信的一个主要不同是:它能实现不同主机间的进程间通信,我们网络上各种各样的服务大多都是基于 Socket 来完成通信的,例如我们每天浏览网页.QQ ...
随机推荐
- WPF流程图制作系列相关基础二
我们现在知道 thumb ,可以让用户自行拖动其在 canvas上移动,在这个而基础上 我们可以试着往流程图方向靠近一下. 我们知道,流程图,都是一个一个的流程块,然后用线连起来的,这一个一个的 ...
- 让iframe可编辑
function EnableEdit() { var editor; editor = document.getElementById("HtmlEdit").contentWi ...
- elixir mac环境
1.升级brew brew update 2.安装 erlang brew install erlang 3.安装Elixir: brew install elixir 终端 iex iex> ...
- 网鼎杯 pwn 记录
题目位置 https://gitee.com/hac425/blog_data/tree/master/wdb babyheap 通过分配和释放构建 2 个 fastbin 链 利用 show 功能, ...
- web 应用响应乱码问题
非西欧语系乱码原因 在没有设置任何内容类型或编码之前,HttpServletResponse使用的字符编码默认是ISO-8859-1.也就是说,如果直接输出中文,在浏览器上就会看到乱码. 有两种方式可 ...
- 带你从零学ReactNative开发跨平台App开发[react native SqlLite 终极运用](十二)
ReactNative跨平台开发系列教程: 带你从零学ReactNative开发跨平台App开发(一) 带你从零学ReactNative开发跨平台App开发(二) 带你从零学ReactNative开发 ...
- react的基本概念
数据流向 数据的改变发生通常是通过用户交互行为或者浏览器行为(如路由跳转等)触发的,当此类行为会改变数据的时候可以通过 dispatch 发起一个 action,如果是同步行为会直接通过 Reduce ...
- Vue2学习笔记:组件(Component)
组件 组件(Component)是 Vue.js 最强大的功能之一.组件可以扩展 HTML 元素,封装可重用的代码.在较高层面上,组件是自定义元素, Vue.js 的编译器为它添加特殊功能.在有些情况 ...
- SQLServer中DataLength()和Len()两内置函数的区别
最近工作中遇到了个问题:在数据库中声明字段类型时char(4),但实际只存储了‘DCE’三个字母,程序中拼装以该字段作为key的Map中,会把‘DCE’+空格作为其Key,这样造成用没加空格的‘DCE ...
- MsSQL使用加密连接SSL/TLS
说明 应用程序通过未加密的通道与数据库服务器通信, 这可能会造成重大的安全风险.在这种情况下, 攻击者可以修改用户输入的数据, 甚至对数据库服务器执行任意 SQL 命令. 例如,当您使用以下连接字符串 ...