网络中的进程

socket解决的是网络中进程间的通信,其首要解决的就是如何在网络中找到目标进程,这就要求进程拥有唯一性的索引,方便查找连接。

一台机器上,进程与进程之间通行,以PID作为唯一标识。但是在网络中,不同的机器,PID可能重复。

然而,网络层的IP 可以唯一标识主机,传输层的 tcp协议和端口号 则能够唯一标识主机中的进程。

因此: ip地址+协议+端口 = 网络中的一个进程

socket

就目前而言,几乎所有的应用程序都是采用socket,而现在又是网络时代,网络中进程通信是无处不在,这就是我为什么说“一切皆socket”。

socket位于应用层和传输层之间的一个抽象层,封装传输层的各种复杂操作,提供几个简单的接口供应用层调用。

socket的主要作用是实现在网络中 进程之间的通信

服务端和客户端 统一使用 socket提供的api进行通信。

socket三次握手 (TCP)

client客户端调用 connect() 方法时,即开始进行建立tcp连接(三次握手)中的 第一次握手(阻塞等待服务端的第二次握手)。

server服务端开始调用 accept() 方法,完成 第二次握手(阻塞等待客户端的第三次握手)。

client客户端 connect() 方法收到第二次握手,进行 第三次握手connect() 方法完成执行。

server服务端 accept() 方法收到第三次握手,完成执行。

通信

socket使用的 “ 打开 -> 读写 -> 关闭 ” 这种模式进行的操作。

这种模式将socket看成一个特殊的 “文件”,提供一些函数对其进行 “IO操作”。

服务端和客户端通过读取这个中间 “文件” 来进行通信。

具体的I/O操作函数有一下几种方式

  • read()/write()

  • recv()/send()

  • readv()/writev()

  • recvmsg()/sendmsg()

  • recvfrom()/sendto()

node中的socket编程

node中跟socket相关的网络模块有两个:

  • net

  • http

net为最底层,以事件驱动机制将socket的接口进行封装,提供socket的相关操作。

http在net的基础上,基于http协议进行再一次封装,将请求分成http头和http体,提供基于request和response的基本操作。

net模块

net模块是node的原生模块,是对tcp层的封装(socket)。

提供了两个类的定义:

  • net.Socket (实现node中的socket操作)

    • 事件: ‘lookup’
    • 事件: ‘connect’
    • 事件: ‘data’
    • 事件: ‘end’
    • 事件: ‘timeout’
    • 事件: ‘drain’
    • 事件: ‘error’
    • 事件: ‘close’
  • net.Server (基于socket,再次封装成服务端API)

    • 事件: ‘listening’
    • 事件: ‘connection’
    • 事件: ‘close’
    • 事件: ‘error’

提供了一些基于两个类的基本操作

  • net.createServer([options], [connectionListener])

  • net.connect(options, [connectionListener])

  • net.createConnection(options, [connectionListener])

  • net.connect(port, [host], [connectListener])

  • net.createConnection(port, [host], [connectListener])

  • net.connect(path, [connectListener])

  • net.createConnection(path, [connectListener])


服务端使用

var net = require('net');var server = net.createServer(function(clientSocket){...
})server.listen(10000,'127.0.0.1',function(){console.log('监听开始')
})

客户端使用

var net = require('net');var clientSocket = net.connect({port:10000,host:'127.0.0.1'
},function(){console.log('tcp连接建立成功');
})
...

其中具体的通信使用事件驱动机制。

clientSocket.on('data',function(){...
})
...

http模块

http模块在net的基础上,提供针对应用层http协议的专门API。

http模块以request和response为基本操作单位,封装net.Socket,将获取到的数据data,分成请求头和请求体。

提供了五个类的定义:

  • http.Server (基于net.Server的再次封装)

    • 事件: ‘request’
    • 事件: ‘connection’
    • 事件: ‘close’
    • 事件: ‘checkContinue’
    • 事件: ‘connect’
    • 事件: ‘upgrade’
    • 事件: ‘clientError’
  • http.ServerResponse (基于net.Socket的再次封装)

    • 事件:’close’
  • http.ClientRequest (基于net.Socket的再次封装)

    • 事件: ‘response’
    • 事件: ‘socket’
    • 事件: ‘connect’
    • 事件: ‘upgrade’
    • 事件: ‘continue’
  • http.Agent

  • http.IncomingMessage

服务端使用

var http = require('http');var server = http.createServer(function(request,response){...
})// 或者var server = new http.Server();
server.on('request',function(request,response){...
})server.listen(10000,'127.0.0.1',function(){console.log('监听开始')
})

客户端使用

var http = require('http');var request = http.request({host : '127.0.0.1',method : 'GET',path: '/'..
})request.on('response',function(response){...
})

url模块

url模块常常配合http模块,对url进行处理。

                               url.parse(string).query|url.parse(string).pathname      ||                   ||                   |------ -------------------
http://localhost:8888/start?foo=bar&hello=world---       -----|          ||          |querystring(string)["foo"]    ||querystring(string)["hello"]

通过url模块,可以创建一个路由机制

var http = require('http');
var url = require('url');
var querystring = require('querystring');var routeHandle = {};routeHandle['/'] = function(response){...
}routeHandle['/upload'] = function(response){...
}http.createServer(function(request,response){var pathname = url.parse(request.url).pathname;route(routeHandle,pathname,request,response);}).listen(10000,'127.0.0.1');function route(handle,pathname,request,response){if (typeof handle[pathname] === 'function') {handle[pathname](response);} else {console.log("该路由没有处理器: " + pathname);}
}

静态文件处理

一个完整的http服务器,除了几个特定的url路径处理之外(即后台action),还应该对静态文件请求做处理。

var http = require('http');
var url = require('url');
var path = require('path');
var fs = require('fs');var MIME = {"css": "text/css","gif": "image/gif","html": "text/html","ico": "image/x-icon","jpeg": "image/jpeg","jpg": "image/jpeg","js": "text/javascript","json": "application/json","pdf": "application/pdf","png": "image/png","svg": "image/svg+xml","swf": "application/x-shockwave-flash","tiff": "image/tiff","txt": "text/plain","wav": "audio/x-wav","wma": "audio/x-ms-wma","wmv": "video/x-ms-wmv","xml": "text/xml"}...function route(handle,pathname,request,response){// path.extname(relPath) 获取文件后缀名if(path.extname(pathname)){// 静态文件 处理doStaticFile(pathname,response);}else{// action 处理...}
}function doStaticFile(relPath,response){fs.exists(relPath,function(exists){if(!exists){response.writeHead(404, {'Content-Type': 'text/plain'});response.write("请求的路径不存在:" + relPath);response.end();}else{fs.readFile(relPath,'binary',function(err,file){if(err){// 服务器异常response.writeHead(500, {'Content-Type': 'text/plain'});response.end();}else{// 返回静态文件var suffix = path.extname(realPath);// 由于extname返回值包含”.”,所以通过slice方法来剔除掉”.”var mime = MIME[suffix.slice(1)] || 'text/plain';response.writeHead(200, {'Content-Type': mime});response.write(file, "binary");response.end();}})}})}http.createServer(function(request,response){var pathname = url.parse(request.url).pathname;route(routeHandle,pathname,request,response);}).listen(10000,'127.0.0.1');

这里就基本实现了一个http服务器,但在静态文件的处理上还有所欠缺。

对于静态资源的请求,每次都是通过读取文件,当请求过多时,会损坏硬盘IO。

因此需要使用缓存,从而减轻硬盘的IO损坏。

参考博文:

  • 简单理解Socket - Samaritans - 博客园

  • Socket通信原理和实践 - 张勤一 - 博客频道 - CSDN.NET

  • 深入浅出NodeJS——数据通信,NET模块运行机制 | 小胡子哥的个人网站

  • net模块中文API

  • http模块中文API

  • 详解Node.js的http模块之http模块概述 - IT笔录

  • Http模块 – JavaScript 标准参考教程(alpha)

  • 用NodeJS打造你的静态文件服务器 - CNode技术社区

Socket总结 node搭建简单的http服务器相关推荐

  1. python搭建web服务器_Python搭建简单的web服务器

    Python搭建简单的web服务器 1.win+R输入cmd打开命令行 2.通过 cd 进入到你保存 HTML 文件的目录.例如:H:\D3\d3 输入 cd\ 指令进入到C盘的根目录.(CD(更改目 ...

  2. 开发板搭建简单的Web服务器

    开发板搭建简单的Web服务器 BOA服务器是一个小巧高效的web服务器,是一个运行于Linux或unix下的,支持CGI.适合于嵌入式的单任务的服务器,源代码开放,性能高 BOA是非常小巧的web服务 ...

  3. 使用VLC media player搭建简单的流媒体服务器

    作为程序员,很多时候需要测试流媒体服务功能,VLC media player就可以轻松的将视频.本机画面.笔记本摄像头的内容发布为流媒体服务,在其他网络联通的地方访问,下面只说主要过程. 首先安装VL ...

  4. 新狼邮箱服务器,搭建简单的邮件服务器+动态域名在互联网中使用

    利用server2003搭建简单的邮件服务器,使用动态域名做mx记录可以在互联网中使用,开始之前我copy了一些资料让大家了解一下pop3和smtp. POP3(Post Office Protoco ...

  5. Ubuntu 搭建简单的Web服务器

    Ubuntu 搭建简单的Web服务器 一.搭建工具 二.搭建步骤 2.1Apche工具安装 2.2打开火狐浏览器 三.实现文件浏览功能 一.搭建工具   在这个实验上我用的是apche搭建的web服务 ...

  6. PC上搭建简单的FTP服务器(仅用于局域网)

    PC上搭建简单的FTP服务器(仅用于局域网) 转载请附原文链接:http://blog.fandong.me/2017/07/16/PC-FTP/ 第一步:打开控制面板选择卸载程序(查看方式为类别) ...

  7. FTP服务器安装+NGINX搭建简单的图片服务器(Linux)

    ftp+nginx实现简单的图片服务器 最近在做个人网站,设计到图片的上传和保存,于是想做一个专门存图片的服务器.以前用过一个tomcat web服务器做图片的服务器,但缺点就是必须和部署系统在同一台 ...

  8. Flask搭建简单图片识别服务器

    Flask搭建简单手写数字识别服务器 困惑我好几天的问题终于解决了,基础还是不太牢固啊,特写这篇文档记录一下,一步一步的开始用flask搭建分类服务器,主要分类MNIST数据集,从客户端(这里指浏览器 ...

  9. Unity搭建简单的图片服务器

    具体要实现的目标是:将图片手动拷贝到服务器,然后在Unity中点击按钮将服务器中的图片加载到Unity中. 首先简答解释下 WAMP(Windows + Apache + Mysql + PHP),一 ...

最新文章

  1. 【HTML】兴唐第二十八节课之初识HTML
  2. 68页PPT教你撰写一篇优秀的机器学习研究论文!
  3. 第三百二十七天 how can I 坚持
  4. CV之MTCNN:MTCNN算法过程及其相关思路配图集合
  5. 【linux家常菜】redhat 6.5 安装yum
  6. DevExpress第三方控件汉化的全部代码和使用方法
  7. token在浏览器和服务端接收和发送
  8. 经典面试题|讲一讲JVM的组成
  9. photoshop cs5快捷键的用法总结
  10. 历时两年,微软物联网安全服务 Azure Sphere 全面上线!
  11. 【云周刊】第173期:直击数博|阿里胡晓明:用100亿的投入撬动1000亿的脱贫效应...
  12. Windows 命令行基础(博主推荐)
  13. LINUX修改网卡MAC地址
  14. 斜度符号标注_机械图纸尺寸标注规则
  15. Qt程序实现自动重启
  16. c#重写TabControl控件实现关闭按钮的方法
  17. 最长上升子序列(LIS)题目合集
  18. 写给人类的机器学习 一、为什么机器学习重要
  19. win10系统要求配置_观察者系统还原游戏配置要求高吗?Observer: System Redux硬件一览!...
  20. 零基础该怎样开始学编程?

热门文章

  1. 虞美人【黑夜流萤】黄昏把酒上阁楼,月下多少幽梦,锁心头。
  2. 一、java程序运行机制
  3. 深度学习中的不确定性详解
  4. C语言中有引用吗?reference
  5. 20221203英语学习
  6. 预测超级计算机排名2020,足球超级计算机预测2019/2020英超联赛排名
  7. 于娟临终前的忠告(一) 此博文包含图片
  8. 【ACM- OJ】《Magical Forest》C++
  9. 数据结构——单循环链表的
  10. YOLO v5 python版本TensorRT推理