网络编程基础【day08】:socke编程入门

本节内容

  1. OSI七层模型
  2. socke通信介绍
  3. 简单socket实例
  4. 通过socket实现简单ssh客户端

OSI七层模型

socke通信介绍

一、概述   

  socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求。

  socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,对于文件用【打开】【读写】【关闭】模式来操作。socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭)

二、关系图

  • file模块是针对某个指定文件进行【打开】【读写】【关闭】
  • socket模块是针对 服务器端 和 客户端Socket 进行【打开】【读写】【关闭】

三、代码逻辑图

四、socket概念

4.1 Socket Families(地址簇)

  1. socket.AF_UNIX unix本机进程间通信 
  2. socket.AF_INET IPV4 
  3. socket.AF_INET6  IPV6

4.2 Socket Types

  1. socket.SOCK_STREAM  #for tcp
  2. socket.SOCK_DGRAM   #for udp 
  3. socket.SOCK_RAW     #原始套接字,普通的套接字无法处理ICMP、IGMP等网络报文,而SOCK_RAW可以;其次,SOCK_RAW也可以处理特殊的IPv4报文;此外,利用原始套接字,可以通过IP_HDRINCL套接字选项由用户构造IP头。
  4. socket.SOCK_RDM  #是一种可靠的UDP形式,即保证交付数据报但不保证顺序。SOCK_RAM用来提供对原始协议的低级访问,在需要执行某些特殊操作时使用,如发送ICMP报文。SOCK_RAM通常仅限于高级用户或管理员运行的程序使用。
  5. socket.SOCK_SEQPACKET #废弃了

简单socket实例

一、概述

  之前我们只是介绍了soket的概念和一些逻辑图表,下面我们来看看,socket的客户端和服务端到底是怎么用的?

二、socket实例

2.1 客户端

2.1.1 客户端代码逻辑图

2.1.2 客户端代码


1

2

3

4

5

6

7

8

9

10

import  socket   #导入socket模块

client = socket.socket()  #创建socket实例

client.connect(("localhost",6969))  #建立连接

send_data = "hello word!"   #发送的字符串

send_data = send_data.encode() #因为发送是bytes类型,所以这边先转码成bytes类型

client.send(send_data)  #发送数据,这边发送的是字节类型,也就是bytes类型

data = client.recv(1024)  #接收服务端的数据,这边设置接收1024字节  1kb=1024字节

print("server rece:",data.decode())

client.close()   #关闭与服务端的链接

2.2 服务端

2.2.1 服务端代码逻辑图 

2.2.2 服务端代码


1

2

3

4

5

6

7

8

9

10

11

12

import socket

sever = socket.socket()  #创建服务端实例

sever.bind(("localhost",6969))   #绑定客户端ip和端口

sever.listen()   #监听端口

print("我在电话了....")

conn,addr = sever.accept()   #接收客户端,并且返回连接标志位(conn)实例,和对方的ip地址(addr)

data = conn.recv(1024)   #接收客户端发过来的数据,接收的也是bytes类型的数据

print("我的电话来了")

print("client data:",data.decode())

conn.send(data.upper())  #发送数据至服务端,注意这边发送的也是字节类型,是bytes类型

sever.close()  #关闭服务端

三、总结

  1. python2中可客户端或者服务端均可发送字符串和字节,但是在python3中只能发字节,也就bytes类型的比特流
  2. 服务端接收客户端的链接时,会返回跟客户端的链接标志位的实例和对方ip地址+随机端口号
  3. 此例子只是TCP/IP协议的socket链接,后面继续学习UDP的链接

通过socket实现简单ssh客户端

一、概述

  本篇博客讲一下,如果socket客户端断了,另外的客户端怎么接入服务端,还有模拟ssh的链接等。

二、socket发送中文

  因为在python 3中只能接受bytes类型的数据,bytes类型只能接受ASCII码里面的数据类型。因为bytes类型是一个ASCII 0-255的数字组合。所以在客户端向服务端传中文时一定要先转成bytes类型,也就是encode(),接收方需要解码,也就是decode()才能识别中文。

2.1、发送中文代码

①客户端


1

2

3

4

5

6

7

8

9

10

11

12

13

14

import  socket

client = socket.socket()

client.connect(("localhost",6969))

msg = "小高最帅了"

client.send(msg.encode())  #传中文至服务端,需要先编码

server_data  = client.recv(1024)

print("recv:",server_data)   #未解码

print("recv:",server_data.decode())   #解码

client.close()

#输出

recv: b‘\xe5\xb0\x8f\xe9\xab\x98\xe6\x9c\x80\xe5\xb8\x85\xe4\xba\x86‘  #bytes类型

recv: 小高最帅了   #字符串

②服务端


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

import socket

sever = socket.socket()

sever.bind(("127.0.0.1",6969))  #绑定ip地址和端口

sever.listen()   #监听

conn,address = sever.accept()   #获取接收实例和ip地址

print("电话来了")

client_data = conn.recv(1024)   #接收客户端数据

print("recv:",client_data)

print("recv:",client_data.decode())

conn.send(client_data)   #发送给客户端

sever.close()

#输出

电话来了

recv: b‘\xe5\xb0\x8f\xe9\xab\x98\xe6\x9c\x80\xe5\xb8\x85\xe4\xba\x86‘  #bytes类型

recv: 小高最帅了   #解码后的结果

注意了:所有的数据发送和接收都用bytes类型就可以了,省的有什么异常情况。

三、重复发送和多次接收

  上面的代码只能客户端只能发送一次,服务端接收一次,就这么结束了,感觉很不爽,那怎么实现客户端发送多次,服务端接收多次呐?

3.1、重复发送和多次接收代码

①客户端

说明:客户端在发送处设置死循环(while  True),实现重复发送。


1

2

3

4

5

6

7

8

9

10

11

12

import  socket

client = socket.socket()

client.connect(("localhost",6969))

while True:    #进入死循环,设置无限次发送

    msg = input(">>>:")

    client.send(msg.encode())

    data  = client.recv(1024)

    print("recv:",data.decode())

client.close()

②服务端

说明:服务端在接收时,设置死循环,实现重复接收。


1

2

3

4

5

6

7

8

9

10

11

12

13

import socket

sever = socket.socket()

sever.bind(("127.0.0.1",6969))

sever.listen()

conn,address = sever.accept()   #接收连接实例

print("电话来了")

while True:   #设置死循环,接收多次

    data = conn.recv(1024)

    print("recv:",data.decode())

    conn.send(data)

sever.close()

注:这边注意了,在服务端,while True千万不能写在conn,address = sever.accept()前面,这个是为什么呢?因为客户端跟服务端只能实现建立一个连接,如果你把while True放在前面,则服务端接收数据后,又要重新建立一个新的等待连接,这样,客户端和服务端都会卡主。

服务端的代码如下:

表现现象:

3.2、处理多个链接

说明:我们在客户端一起链接服务端,我们都知道,一个服务端只能跟一个客户端进行链接通信,那如果说,我这个正在通信的客户端断开跟服务端的通信,那其他的某个客户端就能跟客户端正常通信了,这个实验一定要在Linux服务器上去完成,因为在Windows上就是只要客户端一断开,服务端就断开了。

跟上面一样,客户端的代码没有变,我们现在来变一下服务端的代码:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

import socket

sever = socket.socket()

sever.bind(("127.0.0.1",6969))

sever.listen()

while True#在建立连接之前加一个死循环

    conn,address = sever.accept()

    print("电话来了")

  count = 0   #加一个计数器

    while True:

        data = conn.recv(1024)

     if not data:break   #这边如果接受客户端数据为空,则重新建立连接

        print("recv:",data.decode())

        conn.send(data)

     count += 1

sever.close()

注意:上面if not data:break这段代码不写的后果是:当客户端断开链接时,服务端进入死循环,不断接收客户端的空数据。

现象如图:

①客户端

②服务端

3.3、 客户端发送数据为空

说明:我们之前演示都是客户端输入内容,服务端给出相应,那客户端输入的是空的话,服务端会有什么反映呐?

客户端代码如图:

服务端代码跟上面的一样,执行结果如下:

客户端:

服务端:

原因是:客户端输入的为空,服务端还一直以为客户端在send,然后都卡主了。

那代码怎么改进呢?代码改进如下:

客户端代码:


1

2

3

4

5

6

7

8

9

10

11

12

13

import  socket

client = socket.socket()

client.connect(("localhost",6969))

while True:

    msg = input(">>>:")

    if len(msg) == 0:continue   #这边判断输入的字符是否为空,为空就跳过

    client.send(msg.encode())

    data  = client.recv(1024)

    print("recv:",data.decode())

client.close()

表现现象:

客户端:

服务端:

四、模拟ssh客户端

4.1、模拟ssh访问

说明:以下代码,是在Linux下环境,而且还是python2.7的环境,如果是python 3的话,需要编码和解码。

①客户端


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

#! /usr/bin/env python

# -*- coding:utf-8 -*-

import  socket

client = socket.socket()

client.connect(("localhost",6969))

while True:

    msg = raw_input(">>>:")

    if len(msg) == 0:continue

    client.send(msg)

    data  = client.recv(1024)

    print(data)

client.close()

②服务端


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

#! /usr/bin/env python

# -*- coding:utf-8 -*-

import socket,os   #导入os模块

sever = socket.socket()

sever.bind(("127.0.0.1",6969))

sever.listen(5)  #最大允许有多少个链接

while True:

    conn,address = sever.accept()

    print("电话来了")

    count = 0

    while True:

        data = conn.recv(1024)

        if not data:break

        res = os.popen(data).read()   #调用linux命令

        conn.send(res)   #执行的命令返回值

sever.close()

注:conn.send(res)这边如果需要发送全部的话,需要conn.sendall(res)

4.2、下载文件

①客户端


1

2

3

4

5

6

7

8

9

10

11

12

13

import  socket

client = socket.socket()

client.connect(("localhost",6969))

while True:

    msg = input(">>>:")

    if len(msg) == 0:continue

    client.send(msg.encode())

    data  = client.recv(1024000)   #这边设置的大一点,防止文件的内容接收不到

    with open("test_put","wb") as test_put_file:   #把下载下来的内容写入到文件中

        test_put_file.write(data)

client.close()

②服务端


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

import socket

sever = socket.socket()

sever.bind(("127.0.0.1",6969))

sever.listen()

conn,address = sever.accept()

print("电话来了")

while True:

    data = conn.recv(1024)

    if not data:

        print("数据为空")

        break

    with open("test","rb") as test_file:

        all_data_bytes = test_file.read()   #读取需要下载的文件,发送给客户端

    conn.sendall(all_data_bytes)

sever.close()

注意:这边客户端的接收时有限制的,如果超出了客户端的限制,客户端只接收自己的一部分,而剩余的会在还是在缓冲去,下一次服务端再send的时候,不会发新数据,先把缓冲区剩下的数据发送到客户端。

如图:

时间: 2024-10-14 10:23:14

网络编程基础【day08】:socke编程入门的相关文章

Java笔记二十三.网络编程基础与UDP编程

网络编程基础与UDP编程 转载请表明出处:http://blog.csdn.net/u012637501(嵌入式_小J的天空) 一.网络编程基础 1.TCP/IP协议:TCP/IP协议是一个非常实用的网络应用程序通信协议,包括TCP(传输控制协议)和IP地址(计算机唯一标识号). 2.IP地址:IP在互联网中能唯一标识一台计算机,是每一台计算机的唯一标识(身份证),通过这个标识号来指定接收数据的计算机和识别发送数据的计算机,该标识号即为IP地址. (1)Ipv4:指在计算机中IP地址用4个字节(

网络编程基础之TCP编程学习(一)

网络编程基础了解 socket套接字 socket是一种通讯机制,它包含一整套的调用接口和数据结构的定义,他给应用程序提供了使用如TCP/UDP等网络通讯的手段. linux中的网络编程通过socket接口实现,socket既是一种特殊的IO,提供对应的文件描述符.一个完整的socket都有一个相关描述{协议,本地地址,本地端口,远程地址,远程端口};每个socket有一个本地唯一Socket,由操作系统分配. 定位某个计算机用IP,定位某个服务用端口. 创建Socket #include <s

编程基础知识分享——编程开始之前

对我来说,编程这件事与其说是工作,不如说是兴趣.尽管和自己理想中的编程比,自己的所谓编程只不过是小打小闹,但是现在又有多少所谓的IT从业者是做真正的编程?产业化的今天,其实真的没有必要区分所谓的程序员和码农,每个人的路线和生活都不相同,也不可能相同,有人学编程只是为了一份工作,有人纯粹为了爱好.我的理解,无论出发点如何,只要尊重自己的选择,能够有所收获就够了. 这系列文章,是自己当初学习编程的一些方法和经验,整理了一下,可以分成几块记录.对于专业的程序员,我的经验并不适合,一些计算机专业出身的朋

第1章 网络编程基础(2)——Socket编程原理

Socket编程原理 Socket是网络通信端点的一种抽象,它提供了一种发送和接收数据的机制. 流socket(SOCK_STREAM):双向.有序.无重复.并且无记录边界 数据报Socket(SOCK_DGRAM):双向.保留记录边界 面向连接的操作比无连接的操作效率低,但数据的安全性更高. Socket通信流程 IP地址标志主机,端口号标志进程,IP加上端口号才能确定连接目标. 一个网络连接需要以下5种信息: 本地协议端口:指出接收报文或数据的进程. 本地主机地址:指出接收数据包的主机. 远

第二周:神经网络的编程基础----------2、编程作业常见问题与答案(Programming Assignment FAQ)

Please note that when you are working on the programming exercise you will find comments that say "# GRADED FUNCTION: functionName". Do not edit that comment. The function in that code block will be graded. 1) What is a Jupyter notebook? A Jupyt

IOS学习之十七:Grand Central Dispatch(GCD)编程基础

IOS学习之十七:Grand Central Dispatch(GCD)编程基础 有过编程经验的人,基本都会接触到多线程这块. 在java中以及Android开发中,大量的后台运行,异步消息队列,基本都是运用了多线程来实现. 同样在,在ios移动开发和Android基本是很类似的一种模型. 但是很多时候,在应用开发中,我们会发现本身并没有自己编码去处理一些并发的事件,去开辟新的子线程等等. (虽然一般的调用sdk发起一个网络请求,系统都是会默认给你新起一个线程去处理的). 整个程序看上去基本就是

初识MATLAB之编程基础一

之前4篇随笔初识MATLAB之文件读取,初识MATLAB之矩阵,初识MATLAB之运算符与字符串,初识MATLAB之数据类型介绍了MATLAB基础.接下来分2篇随笔来介绍MATLAB之编程基础.其中编程基础一讲述变量,语句及控制结构.编程基础二讲述M文件及函数. 一 变量和语句 1.1 变量 变量命名:有一些命名规则. 1)对字母大小写敏感. 2)开头必须是字母. 3)不能使用关键字.关键字共有20个(可通过命令iskeyword查询,如下所示) >> keywords= reshape(is

python全栈开发从入门到放弃之socket网络编程基础

网络编程基础 一 客户端/服务器架构 1.硬件C/S架构(打印机) 2.软件C/S架构 互联网中处处是C/S架构 如黄色网站是服务端,你的浏览器是客户端(B/S架构也是C/S架构的一种) 腾讯作为服务端为你提供视频,你得下个腾讯视频客户端才能看它的视频) C/S架构与socket的关系: 我们学习socket就是为了完成C/S架构的开发 为何学习socket一定要先学习互联网协议: 1.首先:本节课程的目标就是教会你如何基于socket编程,来开发一款自己的C/S架构软件 2.其次:C/S架构的

用Netty开发中间件:网络编程基础

用Netty开发中间件:网络编程基础 <Netty权威指南>在网上的评价不是非常高,尤其是第一版,第二版能稍好些?入手后高速翻看了大半本,不免还是想对<Netty权威指南(第二版)>吐槽一下: 前半本的代码排版太糟糕了,简直就是直接打印Word的版式似的. 源代码解析部分的条理性和代码排版好多了,感觉比其它部分的质量高多了. 假设你是刚開始学习的人可能会感觉非常具体,差点儿每部分都会来一套client和服务端的Demo.假设你不是入门者的话可能会感觉水分比較多. 最后一部分高级特性

Java网络编程基础【转】

网络编程 网络编程对于很多的初学者来说,都是很向往的一种编程技能,但是很多的初学者却因为很长一段时间无法进入网络编程的大门而放弃了对于该部分技术的学习. 在 学习网络编程以前,很多初学者可能觉得网络编程是比较复杂的系统工程,需要了解很多和网络相关的基础知识,其实这些都不是很必需的.首先来问一个问题:你 会打手机吗?很多人可能说肯定会啊,不就是按按电话号码,拨打电话嘛,很简单的事情啊!其实初学者如果入门网络编程的话也可以做到这么简单! 网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据.