UDP/TCP套接字编程

一、UDP套接字编程

采用python的socket库作为编程方式

1.1socket库的函数

函数名参数作用
gethostname()无参数返回主机名称
gethostbyname(‘主机名’)主机名将主机名转换为ipv4地址
gethostbyname_ex(‘主机名’)主机名返回主机名、主机别名列表、主机IP地址列表
gethostbyaddr(‘ip地址’)ip地址返回三元组(主机名,主机别名列表,主机IP地址列表)
getservbyport(‘端口号’,‘协议名’)端口号,协议名返回该端口号的服务名,仅限于本机
getservbyname(‘服务名’,‘协议名’)服务名,协议名返回该服务所在的端口号
getsockname()无参数返回自己捆绑的IPv4地址
getaddrinfo(‘主机号’,‘端口号’)主机名,端口号返回五元组,用于获取主机名的地址信息,兼容IPv4和IPv6
socket(family,type)family
socket.AF_INET(IPv4)
socket.AF_INET6(IPv6)
socket.AF_UNIX(同一台机器之间的通信)
socket.SOCK_STREAM(流式for TCP)
socket.SOCK_DGRAM(报文式数据包for UDP)
socket.SOCK_RAW(原始套接字,普通的套接字无法处理ICMP,IGMP等报文,而SOCK_RAW可以;其次,SOCK_RAW也可以处理特殊的IPv4报文;此外,利用原始套接字,可以通过IP_HDRINCL套接字选项由用户构造IP头)
socket.SOCK_SEQPACKET(可靠的连续数据包格式)
创建一个已知的IP地址和协议类型的连接
connect((host,port))(主机名,端口号)与此主机的端口进行远程连接,注意括号
gettimeout()无参数返回socket超时时间,单位为s
settimeout(timeout)超时时间设置socket超时时间

1.2socket库的方法

1.2.1connect(address):

链接到一个address对应的远程socket。如果连接被中断,这个方法会等待直到连接完成,或者抛出一个socket.timeout错误。

1.2.2accept():

接受一个连接,但是前提是socket必须已经绑定了一个地址,在等待建立连接。在默认情况下,socket是阻塞式的,意思就是socket的方法的调用在任务完成之前是不会返回的。
调用accept方法时,socket会进入“waiting”状态。客户请求连接时方法建立连接并返回服务器。accept方法返回的是一个含有两个元素的元组(connection,address)。第一个元素connection是新的socket对象,服务器必须通过他与客户通信;第二个元素address是客户的IP地址。

1.2.3recv(bufsize):

从socket接收数据,注意是byte类型,bufsize指定一次最多接受的数据大小。

1.2.4recvfrom(bufsize):

与上一个recv方法的区别为返回值除了数据还有发送数据的地址,返回值是一个数据,地址对(data,address)。

1.2.5send(bytes):

发送数据到socket,前提是已经链接到远程socket,返回值是发送数据的量,检查数据是否发送完是应用的责任。

1.2.6sendto(bytes,flags,address):

基本与socket.send()相同

1.2.7close()

关闭连接,当socket.close()执行的时候,与这个链接相关的底层操作也会关闭(如文件描述符),一旦关闭,再对相关的文件对象操作都会失败。

1.2.8bind(address):

将socket对象绑定到一个地址,但是这个地址必须是没有被占用的,否则会连接失败。这里的address一般是一个(ip,port)对

1.2.9listen([backlog]):

监听,使得服务器能接受服务端链接,如果backlog指定了(最少是0,如果比0小,系统默认改成0),限制可以连接的数量,如果没有指定,将指派一个默认的合理值。

1.3客户端代码

from socket import *
serverName = '192.168.100.129'
serverPort = 12000

# AF_UNIX  AF_INEF  AF_INEF6
# SOCK_STREAM  SOCK_DGRAM  SOCK_RAW  SOCK_SEQPACKET
clientSocket = socket(AF_INET,SOCK_DGRAM)

MESSAGE = input("Input lowercase sentence:")

clientSocket.sendto(MESSAGE.encode(),(serverName,serverPort))
message,address=clientSocket.recvfrom(2048)
print(message.decode())

在这里插入图片描述

1.4 服务端代码

from socket import *

serverPort=12000
serverSocket=socket(AF_INET,SOCK_DGRAM)

serverSocket.bind(('',serverPort))

print("THE SERVER IS OK !")

while 1:
    message,address=serverSocket.recvfrom(2048)
    print(address[0])
    serverSocket.sendto(message.decode().upper().encode(),address)

    print(message.decode())
    print(address)

在这里插入图片描述
编程的时候犯了一个错误,就是服务器socket.recvfrom返回的address中是一个包含源IP地址和发送方端口号的,在客户端程序中的clientSocket.sendto(MESSAGE.encode(),(serverName,serverPort))这一行代码中serverPort指的是服务器的端口,而我在服务器代码中还用这个serverPort作为serverSocket.sendto()的端口参数,程序不会报错,但是我在客户端就收不到回传的信息了,因为我的客户端端口并不是serverPort。而且serverSocket.sendto()他需要两个参数,第一个参数是发送的内容,第二个参数是一个目的地址IP和目的地址端口号组成的元组,不能分开。

二、TCP套接字编程

2.1客户端代码

from socket import *
serverName = '192.168.100.129'
serverPort = 12000

# AF_UNIX  AF_INEF  AF_INEF6
# SOCK_STREAM  SOCK_DGRAM  SOCK_RAW  SOCK_SEQPACKET
clientSocket = socket(AF_INET,SOCK_STREAM)
clientSocket.connect((serverName,serverPort))
MESSAGE = input("Input lowercase sentence:")

clientSocket.sendto(MESSAGE.encode(),(serverName,serverPort))
message,address=clientSocket.recvfrom(2048)
print(message.decode())

在这里插入图片描述

2.2服务端代码

from socket import *

serverPort=12000
serverSocket=socket(AF_INET,SOCK_STREAM)

serverSocket.bind(('',serverPort))
serverSocket.listen(1)
print("THE SERVER IS OK !")

while 1:
    connectionSocket,address=serverSocket.accept()
    message=connectionSocket.recv(2048)
    connectionSocket.sendto(message.decode().upper().encode(),address)

    print(message.decode())
    print(address)

在这里插入图片描述
主要注意量两点。第一点是TCP需要经历三次握手,在python的socket包中包装为socket.connect()和socket.accept()方法。第二个就是要注意服务器在建立连接之前生成的是名为serverSocket的TCP欢迎套接字对象,但是这个对象只负责TCP三次握手,握手成功后会交由名为connectionSocket的连接套接字进行处理。欢迎套接字是所有要与服务器通信的客户的起始接触点,连接套接字是随后为每个客户通信而生成的套接字。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值