网络编程通过tcp协议进行聊天对话

网络编程
自从互联网诞生以来,现在基本上所有的程序都是网络程序,很少有单机版的程序了。

计算机网络就是把各个计算机连接到一起,让网络中的计算机可以互相通信。网络编程就是如何在程序中实现两台计算机的通信。

网络编程对所有开发语言都是一样的,Python也不例外。用Python进行网络编程,就是在Python程序本身这个进程内,连接别的服务器进程的通信端口进行通信。

基本概念
IP地址实际上是一个32位整数(称为IPv4),以字符串表示的IP地址如192.168.0.1实际上是把32位整数按8位分组后的数字表示,目的是便于阅读。

IPv6地址实际上是一个128位整数,它是目前使用的IPv4的升级版,以字符串表示类似于2001:0db8:85a3:0042:1000:8a2e:0370:7334。

TCP协议则是建立在IP协议之上的。TCP协议负责在两台计算机之间建立可靠连接,保证数据包按顺序到达。TCP协议会通过握手建立连接,然后,对每个IP包编号,确保对方按顺序收到,如果包丢掉了,就自动重发。

许多常用的更高级的协议都是建立在TCP协议基础上的,比如用于浏览器的HTTP协议、发送邮件的SMTP协议等。

一个TCP报文除了包含要传输的数据外,还包含源IP地址和目标IP地址,源端口和目标端口。

端口有什么作用?在两台计算机通信时,只发IP地址是不够的,因为同一台计算机上跑着多个网络程序。一个TCP报文来了之后,到底是交给浏览器还是QQ,就需要端口号来区分。每个网络程序都向操作系统申请唯一的端口号,这样,两个进程在两台计算机之间建立网络连接就需要各自的IP地址和各自的端口号。

一个进程也可能同时与多个计算机建立链接,因此它会申请很多端口。

TCP编程

什么是 Socket?

Socket又称”套接字”,应用程序通常通过”套接字”向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯。

socket()函数
Python中,我们用socket()函数来创建套接字。

Socket对象(内建)主要方法

服务器端套接字

s.bind() 绑定地址(host,port)到套接字, 在AF_INET下,以元组(host,port)的形式表示地址。

s.listen() 开始TCP监听。backlog指定在拒绝连接之前,操作系统可以挂起的最大连接数量。该值至少为1,大部分应用程序设为5就可以了。

s.accept() 被动接受TCP客户端连接,(阻塞式)等待连接的到来

客户端套接字

s.connect() 主动初始化TCP服务器连接,。一般address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。

s.connect_ex() connect()函数的扩展版本,出错时返回出错码,而不是抛出异常

公共用途套接字函数
s.recv() 接收TCP数据,数据以字符串形式返回,bufsize指定要接收的最大数据量。flag提供有关消息的其他信息,通常可以忽略。

s.send() 发送TCP数据,将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。

s.close() 关闭套接字

服务器

和客户端编程相比,服务器编程就要复杂一些。

服务器进程首先要绑定一个端口并监听来自其他客户端的连接。如果某个客户端连接过来了,服务器就与该客户端建立Socket连接,随后的通信就靠这个Socket连接了。

所以,服务器会打开固定端口(比如80)监听,每来一个客户端连接,就创建该Socket连接。由于服务器会有大量来自客户端的连接,所以,服务器要能够区分一个Socket连接是和哪个客户端绑定的。一个Socket依赖4项:服务器地址、服务器端口、客户端地址、客户端端口来唯一确定一个Socket。

但是服务器还需要同时响应多个客户端的请求,所以,每个连接都需要一个新的进程或者新的线程来处理,否则,服务器一次就只能服务一个客户端了。

#导入 socket和_thread模块
import socket
import _thread
#创建socket对象
serverSocket=socket.socket(family=socket.AF_INET,type=socket.SOCK_STREAM)
#获取本地主机名和端口号
serverSocket.bind(("localhost",8888))
print("服务器等待。。。")
#设置最大连接数,超过后排队
serverSocket.listen(5)
#serverSocket.accpet()会返回两个值一个是客户端实例另一个是客户端地址ip
clientSocket,addr=serverSocket.accept()
#进行多线程获取客户端内容
def jieshoumsg():
    while True:
        #接收小于1024字节的数据并编码成utf-8格式
        msg = clientSocket.recv(1024).decode("utf-8")
        print("客户端说:", msg)
_thread.start_new_thread(jieshoumsg,())
#进行多线程对客户端发送内容
def sendqq():
    while True:
        qq=input("我说:")
        #发送数据并解析成utf-8格式
        clientSocket.send(qq.encode("utf-8"))
_thread.start_new_thread(sendqq(),())

客户端
大多数连接都是可靠的TCP连接。创建TCP连接时,主动发起连接的叫客户端,被动响应连接的叫服务器。

import socket
import _thread
#创建Socket对象
clientSocket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#连接指定的服务端 和端口
clientSocket.connect(("localhost",8888))
print("客户端连接")
#下面就跟服务器的一样了
def jieshoumsg():
    while True:
        msg = clientSocket.recv(1024).decode("utf-8")
        print("服务器说:", msg)
_thread.start_new_thread(jieshoumsg,())

def sendqq():
    while True:
        qq=input("我说")
        clientSocket.send(qq.encode("utf-8"))
_thread.start_new_thread(sendqq(),())

猜你喜欢

转载自blog.csdn.net/mr_li1/article/details/80943448
今日推荐