python网络编程--Socket通信

发布时间 2023-12-01 10:39:07作者: jack_Meng

python网络编程(一)Socket介绍

一:Socket简介

  • 套接字起源于20世纪70年代加利福尼亚大学伯克利分校版本的Unix,即人们所说的BSD Unix。因此,有时人们也把套接字称为“伯克利套接字"或"BSD套接字”。一开始,套接字被设计用在同 -台主机上多个应用程序之间的通讯
  • BSD Socket接口是TCP/IP网络的API
  • 在Linux,Unix和Windows均实现这个接口.BSD Socket的是目前开发网络应用主要接口.绝大部分网络应用均可Socket来开发
  • 一个Socket队列是IP应用的基本单位.两个机器通讯相当于两个机器的两个Socket互相通讯的过程
  • Socket 的本意是插座.每一个激活的socket可以看成是一个跟本地某个IP端口绑定的IP包队列
  • 接口设计者最先是将接口放在Unix操作系统里面的。因此一个激活的Socket被设计成特殊的I/O文件, Socket也是一种文件描述符。 .因此操作类似对一个普通文件操作
  • 套接字有两种(或者称为有两个种族),分别是基于文件型的和基于网络型的

基于文件类型的套接字家族
套接字家族的名字: AF_ _UNIX
unix-切皆文件,基于文件的套接字调用的就是底层的文件系统来取数据,两个套接字进程运行在同一机器,可以通过访问同一个文件系统间接完成通信

基于网络类型的套接字家族
套接字家族的名字: AF_ INET
(还有AF_ INET6被用于ipv6,还有一些其他的地址家族, 不过,他们要么是只用于某个平台,要么就是已经被废弃,或者是很少被使用,或者是根本没有实现,所有地址家族中,AF INET是使用最广泛的-个,python支持很多种地址家族,但是由于我们只关心网络编程,所以大部分时候我么只使用AF_ INET)

二:Socket基本函数

1、创建套接字

socket(socket.AF_INET,socket.SOCK_STREAM)

  • socket.AF_INET:表示是基于网络的套接字家族,因而可以允许在远程 主机之间通信
  • socket.SOCK_STREAM:表示流式模块,基于tcp协议,这样会提供按顺序的,可靠,双向,面向连接的比特流

2、设置端口重用

setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
比如,当我们把程序关闭了,但是操作系统还没有释放端口,再次启动就会报端口被占用的错误,使用setsockopt就解决这种情况

3、绑定

bind((‘127.0.0.1’,8000))
里面一定要是一个tuple类型,绑定ip,端口,ip是部署服务端的ip,如果是127.0.0.1,就表示服务端和客户端要在一台服务器上,端口0-65535,0-1024是操作系统使用,1024后的端口是应用程序使用

4、侦听

listen()
在某个端口上.侦听

5、accept ()

accept () listen侦听后,有客户端进来来调用,如果一直没有客户端来,就会阻塞在这里

6、connect ()

connect((‘127.0.0.1’,8000)) 联接远程某个Socket,里面也要一个tuple类型,ip和端口都填的是服务端的ip和端口
connect函数是客户端用来同服务端连接的

7、发送数据

send(msg.encode(“utf-8”)) 发送数据,需要把字符串转换为bytes

8、接收数据

recv(1024) 接收的数据 ,单位:bytes 这里表示最大接收1024个bytes

Socket 编程模型

  • Socket当前编程模型一般都是C/S结构.即相互通信的网络程序中,一方称为客户程序(client),另一方称为服务程序(server)
  • C/S结构中,客户端向服务器发送请求,服务器作出响应.象常见的浏览器/web服务器,FTP客户端/FTP服务器. 就是典型的C/S结构
  • 一个服务器可以同时接受多个客户端请求
  • 在socket编程中,服务器和客户端的编程流程有一些不同

socket编程的流程图

在这里插入图片描述
服务端流程:创建套接口(socket)→绑定套接口(bind)→设置套接口为监听模式,进入被动接受连接请求状态(listen) →接受请求(accept),建立连接(socket)→读/写数据(recv,send)→终止连接(close)
客户端流程:创建套接口(socket)→与远程服务程序连接(connect)→写/读数据(send/recv)→终止连接 (close)

代码实现

本例子实现是循环接收客户端,只能一个一个连接客户端,还不能并发
1、服务端代码,文件名server.py

#--coding:utf-8--

import socket
'''
socket.AF_INET:表示是基于网络的套接字家族
socket.SOCK_STREAM:表示流式模块,基于tcp协议
'''
#创建套接字
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#绑定ip,端口,ip是部署服务端的ip,如果是127.0.0.1,就表示服务端和客户端要在一台服务器上,端口0-65535,0-1024是操作系统使用,1024后的端口是应用程序使用
server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)   #设置端口重用,比如端口已经关闭了但是操作系统还没有释放,会提示端口占用
server.bind(('0.0.0.0',8000))
#监听
server.listen()

print('staring....')
while True:  #连接循环
    conn , addr = server.accept()
    print(addr)

    while True:   #通信循环
        try:
            data = conn.recv(1024)   #1、单位:bytes 2、最大接收1024个bytes
            if not data:break   #适用于linux操作系统,如果客户端断开了连接,如果不处理在linux系统上,客户端断开后服务端就会进入的无限循环
            print('客户端的数据:',data.decode('utf8'))
            conn.send(data.upper())   #服务端接收到客户端的数据后,变成大写再返回给客户端
        except ConnectionResetError:     #适用于windows系统,如果客户端断开连接,在windows系统就会报ConnectionResetError的错误
            break

    conn.close()
server.close()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

2、客户端代码,文件名称client.py

import socket

client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

#发起连接,服务端的ip和端口
client.connect(('127.0.0.1',8000))

while True:
    msg = input(">>: ").strip() #去掉空格
    if not msg:continue      #如果发的是空就进入下一次循环,如果不处理,当客户端发送一个空字符后服务端就会阻塞在recv处
    client.send(msg.encode("utf-8"))   #将字符串转换为bytes
    data = client.recv(1024)
    print(data.decode("utf8"))

client.close()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

 

【出处】:https://blog.csdn.net/javascript_good/article/details/131432270

=======================================================================================