Socket编程

Socket编程

两种传输层服务的socket类型:

  • TCP:可靠的,字节流的服务
  • UDP:不可靠的服务

TCP套接字编程

套接字:

应用进程与端到端传输协议(TCP或UDP)之间的门户

TCP服务:

从一个进程向另一个进程可靠地传输字节流

流程:

服务器首先运行,等待连接建立

1.服务器进程必须先处于运行状态
  • 创建欢迎socket
  • 和本地端口捆绑
  • 在欢迎socket上阻塞式等待接收用户的连接

客户端主动和服务器建立连接

2.创建客户端本地套接字(隐式捆版到本地port)
  • 指定服务器进程的IP地址和端口号,与服务器进程连接
3.当与客户端连接请求到来时

服务器接受来自用户端的请求,解除阻塞式等待,返回一个新的socket(与欢迎socket不一样),与客户端通信

  • 允许服务器与多个客户端通信
  • 使用源IP和源端口来区分不同的客户端
4.连接API调用有效时,客户端P与服务器建立了TCP连接
Python代码实现
服务器端
#coding=gbk
from socket import*

#1、创建server_socket
server_socket=socket(AF_INET,SOCK_STREAM)

#2、绑定一个IP和端口
host_port=("localhost",8009)
server_socket.bind(host_port)

#3、服务器的Socket监听,listen让Socket处于被动,就可以接收客户端的连接请求
server_socket.listen(1) #只与一个线程通讯
print("-----客户端----")
while True:
    # 4、等待客户端的连接请求,当前函数是线程阻塞的函数,accept返回两个值,第一个:新的Socket 第二个:新socket的地址
    new_socket,clien_socket=server_socket.accept()

    while True:
        # 5、服务器接受客户端发送过来的数据,recv一般用于TCP协议的接收数据,recvfrom用于UDP
        recv_data=new_socket.recv(1024)#data是字节数据

        if len(recv_data)>0:#客户端没有退出,而且发送数据到服务器啦
            print('客户端:',recv_data.decode('utf-8'))
        if recv_data.decode('utf-8')=='exit':
            print('客户端已经退出啦!')
            break

        #发送数据给客户端
        send_data=input('服务器:')
        if len(send_data)>0:
            new_socket.send(send_data.encode('utf-8'))
    # 7、关闭套接字
    new_socket.close()  #new_socket关闭意味着当前客户端的服务已经完成

#关闭整个服务器,但是前面有一个while循环,是执行不到这里的,所以服务器只有强制结束运行
server_socket.close()

客户端
#coding=gbk
from socket import*

client_socket=socket(AF_INET,SOCK_STREAM)

#客户端发送连接的请求(不是传输数据)
#目标服务器的IP和端口号
server_ip_port=("localhost",8009)
client_socket.connect(server_ip_port)
print("-----服务器----")
while True:
    send_data=input('客户端:')
    if len(send_data)>0:
        client_socket.send(send_data.encode('utf-8'))
    if send_data=='exit':
        client_socket.close()
        break

    #客户端接收服务器返回的数据
    recv_data=client_socket.recv(1024)
    print('服务器端:',recv_data.decode('utf-8'))

client_socket.close()
运行结果
实现效果:

客户端与服务器端通信

服务器端

image-20221013110654734

客户端

image-20221013110617256

UDP套接字编程

特点:

在客户端与服务器之间没有连接

传送的数据可能乱序,也可能丢失

  • 没有握手
  • 发送端在每一个报文中明确地指定目标的IP地址和端口号
  • 服务器必须从收到的分组中提取出发送端的IP地址和端口号
Python代码实现
实现效果:

客户端发送什么给服务器,服务器就会发送什么给客户端

客户端
#coding=gbk
from socket import *
#1、客户端可以发送多条 2、客户端如果发送一个'exit'则客户端退出 3、服务器端收到什么就返回什么

# 创建一个UDP协议的套接字,然后发送一条数据到网络上的另一个进程

#1、创建套接字
client_socket=socket(AF_INET,SOCK_DGRAM)

#定义变量,是否退出客户端的标记
flag=True

# 2、定义一个接受消息的目标,8080是一个目标服务器的端口,localhost是目标服务器地址
server_host_port = ('localhost', 8093)

while flag:
    #3、准备发送数据,encode表示按照一种编码格式把数据变成字节数组bytes
    #数据一定是字节数据才能发送
    datas=input('请输入:').encode('utf-8')

    #4、发送数据,标识一个进程是通过IP+端口+协议
    client_socket.sendto(datas,server_host_port)

    #一定可以从服务器接收到放回过来的数据,打印服务器打印的数据
    print("返回的数据是:",client_socket.recvfrom(1024)[0].decode('utf-8'))

    if datas.decode('utf-8')=='exit':
        flag=False

#5、关闭套接字,其实就是释放了系统资源
client_socket.close()
服务器端
#coding=gbk
from socket import *
#1、客户端可以发送多条 2、客户端如果发送一个'exit'则客户端退出 3、服务器端收到什么就返回什么

#1、创建一个服务端的Socket
socket_server=socket(AF_INET,SOCK_DGRAM)


#2、定义服务器端的地址和端口号
host_port=('',8093)#如果服务器是真实的物理小型服务器,IP地址有很多,要任何本机的IP地址都绑定就只用''

#3、服务器端的Socket来绑定地址和端口,只有绑定了地址和端口,才能称之为服务器的Socket
socket_server.bind(host_port)

while True:

    #4、接受客户端发送过来的数据,每次接受1kb数据,收到的每一个数据报,里面是一个元组,元组第一个值是数据内容,第二个值是源地址和源端口号
    data=socket_server.recvfrom(1024)#里面填写的数据为数据的大小

    #服务器收到数据之后原封不动返回,而且是收到哪个客户端的信息就返回给哪个客户端
    socket_server.sendto(data[0],data[1])

    print(data[0].decode('utf-8'))


#5、关闭套接字,释放资源
socket_server.close()
运行效果
客户端

image-20221013135224595

服务器端

image-20221013135239705

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值