功能原理
实现进程之间的通信。客户机进程<--->服务器进程
通过套接字socket实现发送和接受消息。可以理解为门,发送方通过该门来发送消息,接收方通过该门来接受消息。
应用层需要做什么两个进程要实现在庞大的互联网的通信,需要一个唯一可以标识它们的ID,这个ID由 :主机的IP地址 + 端口号 构成,这样一个进程就可以根据ID通过其他层提供的服务来连接到另外的进程进行通信。
应用层需要封装这些信息应用层使用传输层提供的TCP服务来通信
网络层次都是类似于黑盒。对于使用它的上层只暴露提供什么样的服务,上层不会在乎下层通过什么方法提供。
应用层遵守的协议。
公开协议如HTTP SMTP
私有协议如P2P共享应用。
具体应用
web应用
因为是无状态的,后面会讨论怎么解决保存用户状态问题。
HTTP有两种类型:
持久性连接:允许一次连接建立后传输多个内容对象
非持久性连接:只允许一次连接建立后传输一个内容对象
这里对于html解析发现html页面上面有超链接需要重新发送资源请求对象,每个对象都需要重复该过程。
这里说的建立了TCP连接只消耗了1个RTT其实建立的是一种伪连接,真正的TCP建立连接应该是 HTTP请求信息到达web服务器(伴随着第三次握手)这样才真正建立了TCP连接。
这里会出现RTT分析
一般是根据具体的场景进行分析。
持久性连接:连接建立 1RTT (资源对象a)1RTT (资源对象b)1RTT。如果是带有流水线机制则所有的对象传输只消耗1RTT,用并行来理解。
非持久性连接:连接建立 1RTT (资源对象a)1RTT
(资源对象b) 2RTT (资源对象c)2RTT
method有:get post之类 常见的状态消息码 采用cookie技术记录用户上次访问的记录内容cookie工作原理
cookie文件保存在本地由浏览器管理,cookie记录在服务端也有记录,可以识别浏览器发送过来的请求查看cookie是否有过会话,有的话就把一些状态直接返回给客户端浏览器。
web缓存代理服务器是由用户所在的一个局域网架设的,这样就可以在用户发送二次请求时候,通过局域网设置的cache来返回请求的内容,减少了访问远方服务器的消耗。
cache同时充当服务器和客户端的角色,它满足本地局域网内部的请求,同时也向服务器发送请求来同步自己持有的内容。
SMTP是应用层的协议下层使用TCP进行email消息的封装和传输
邮件通过SMTP发送,然后通过POP3、IMAP(可以接收多媒体邮件)、HTTP来从服务器下载邮件
DNS
建立域名和IP的对应关系
分别是根域名服务器、顶级域名服务器、权威域名服务器DNS查询分类:递归查询、迭代查询
迭代查询本地域名服务器压力大 递归查询容易理解就是推卸责任,找到沿请求路线后返回 DNS的记录缓存刷新机制 如何注册一个域名P2P架构
P2P文件分发
我们讨论一个技术也就是常用的BT种子下载技术(比特洪流)。
tracker是保存了持有资源文件的节点的列表,用户节点通过访问tracker就知道应该尝试性的和哪些节点进行文件传输。文件传输是双向的。
尝试性选择最快速率的四个邻居来传输chunk(文件块)这样是不是会导致马太效应呢?
索引技术
采用p2p传输消息,当一端渴望进行p2p连接时,怎么找到另外的一端呢,就是通过索引,索引建立了消息(需要被传输的消息)和目标端(IP+端口)的映射。
常见的索引方法:
压力问题 效率问题 综合两种的优缺点诞生了层次式覆盖网络结构 Skype软件采用的就是层次式覆盖socket编程
socket是连接应用层和传输层的桥梁,可以理解应用程序通过socket实现网络功能,而socket编程可以实现对TCP和UDP的封装(甚至可以实现附加的一些控制优化实现数据可靠,高效传输)。
socket层应用其实都是由socket编程实现的。socket编程就是抽象化的建立两个应用端进行写数据和读数据的过程。操作系统通过创建socket然后管理socket可以用socket来读和写消息给另外一端的socket程序。
我们知道应用层实现服务必然需要传输层提供支持,这里可以供使用的有TCP和UDP。面对这两者我们采用API的不同的方法来实现建立连接和通信。这里创建socket的时候就需要封装一些tcp需要的东西,比如tcp需要的IP,端口号之类的消息。API里面都有描述。
这是两个通过socket编程(TCP和UDP)实现网络应用简单功能的例子:
https://blog.csdn.net/xiaolixi199311/article/details/78757228
https://blog.csdn.net/Shayne_Lee/article/details/89608232
也可以参考:
一个C/S的socket实现java例子:
client
import java.net.*;
import java.io.*;
import java.util.Scanner;
public class client
{
public static void main(String[] args)
{
String serverName = "localhost";
int port = 6066;
try
{
String string;
Socket client = new Socket(serverName, port);
OutputStream outToServer = client.getOutputStream();
DataOutputStream out = new DataOutputStream(outToServer);
Scanner input = new Scanner(System.in);
InputStream inFromServer = client.getInputStream();
DataInputStream in = new DataInputStream(inFromServer);
while((string =input.nextLine())!="exit"){
out.writeUTF(string);
System.out.println(in.readUTF());
}
}catch(IOException e)
{
e.printStackTrace();
}
}
}
server
package socket;
import java.net.*;
import java.io.*;
public class server extends Thread
{
private ServerSocket serverSocket;
public server(int port) throws IOException
{
serverSocket = new ServerSocket(port);
}
public void run()
{
Socket server = null;
try {
server = serverSocket.accept();
} catch (IOException e) {
e.printStackTrace();
}
DataInputStream in = null;
try {
in = new DataInputStream(server.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
DataOutputStream out = null;
try {
out = new DataOutputStream(server.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
while(true)
{
try
{
String string = in.readUTF();
string = string.toUpperCase();
out.writeUTF(string);
}catch(SocketTimeoutException s)
{
System.out.println("Socket timed out!");
break;
}catch(IOException e)
{
e.printStackTrace();
break;
}
}
}
public static void main(String[] args)
{
int port = 6066;
try
{
Thread t = new server(port);
t.run();
}catch(IOException e)
{
e.printStackTrace();
}
}
}
我们使用的再复杂的网络应用也是通过这些socket一层层如建筑一般构建的。
网友评论