TCP编程(一)[Python]

因为课题原因,需要使用socket通信,以下为自学笔记。

Socket介绍

Socket源自于Unix系统,一切皆文件,socket其实也就是一种特殊的文件,所以socket函数就是对其进行的打开关闭、读写等操作。

 参考张岩林大佬的描述,socket模块就是针对服务器端(Server)和客户端(Client)进行的【打开】【读写】【关闭】操作,具体流程图如下所示:

 实战操作

了解了Socket通信的基本原理以及流程后,开始动手自己编写客户端和服务器端的socket通信。

客户端

首先明白什么事客户端,在发起TCP连接的时候,通常主动发起连接的便是客户端(Client),被动响应连接的称作服务器端(Server)。比如浏览网页的时候,本机就是客户端,访问的网页便是服务器端。

下面是一个简单的基于TCP通信的Socket连接。以客户端为例:

#导入socket库
import socket

# 创建一个socket:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 建立连接:
s.connect(('www.baidu.com.cn', 80))
cmd = raw_input("Please Input Some Commands")
s.sendall(cmd)

#定义一个buffer来接收数据
buffer = []
#利用while循环实现接收所有数据的功能
while True:
    d = s.recv(1024)
    if d:
        #append操作,不断将d中的数据添加给buffer
        buffer.append(d)
    else:
        break
#将buffer中的元素联接成一个新的字符串
data = b''.join(buffer)
print(data)

#关闭连接
s.close()

首先,导入socket库,创建一个socket通信,其中socket.AF_INET指的是使用IPv4协议,socket.AF_INET6代表IPv6协议(IPV4和IPV6协议的区别自行谷歌) 

然后SOCK_STREAM代表使用流式socket,for TCP,SOCK_DGRAM指的是数据包式socket,for UDP

到这里,一个正常的socket对象已经创建成功,接下来要建立连接。连接需要服务器的两个参数:IP地址和端口号,此处使用了域名直接转IP地址,而80端口是Web服务的标准端口,通常都会预留一些端口给专用的服务,例如SMTP服务是25端口,FTP服务是21端口,工业协议Modbus/TCP是502端口等等。将两个参数作为一个元组(tuple)进行输入。

接下来可以接收服务器返回的数据,可以调用recv(max)函数来指定一次最多接收的字节数量,可以用一个while循环来实现接收返回数据的功能。

最后使用s.close()来关闭连接即可。

服务器端

通过第一张socket通信流程图可以看到,服务器端实现要比客户端更加复杂。

首先服务器端要绑定一个端口并且进行监听,如果监听到客户端发送过来的请求,那么服务器端就与客户端建立socket连接。

那么服务器如何区分到底应该和哪个客户端进行绑定连接的呢。一个Socket由以下四个参数来唯一确定:

  • 服务器地址
  • 服务器端口号
  • 客户端地址
  • 客户端端口号

首先,仿照客户端通信,先创建一个socket通信

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

然后绑定需要监听的地址和端口号, 但是一台计算机中可能存在多块网卡,可以通过IP地址来区分绑定到哪一张网卡,例如0.0.0.0表示绑定到所有网络地址,127.0.0.1表示绑定到本机地址,此时,客户端必须同时在本机运行才能够正常连接,外部的计算机是无法进行连接的。

接下来指定绑定的端口号,端口号小于1024指的是Internet标准服务的端口,需要管理员权限,大于1024的端口则可以任意使用。

# 绑定IP地址和端口号:
s.bind(('127.0.0.1', 8888))

按照流程图,接下来需要进行监听操作,调用listen()方法可以实现

#监听端口
#listen()传入的参数为等待连接的最大数量
s.listen(5)
print('Waiting for connection...')

接来下,依然利用一个while循环来实现接收客户端的连接操作。

while True:
    # 接受一个新连接,并返回新的套接字和IP地址
    conn, addr = s.accept()
    print("Connected to",addr)
    conn.send("Hello World")
    conn.close()

总结

今天先写到这吧,过两天写一下整体的实现,和如何创建新线程的方法进行连接。新手写博,只是做个笔记。

参考链接

https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001432004374523e495f640612f4b08975398796939ec3c000

http://www.cnblogs.com/aylin/p/5572104.html

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值