Linux网络编程

TCP/IP概述

在这里插入图片描述
◆ 关于传输层的TCP和UDP协议
TCP是通过三次握手建立的传输控制协议,而UDP是一种无连接的用户数据报协议,实时性较好。

• 当对数据可靠性要求较高或者网络状况不是很好时,采用TCP协议;
• 如果对实时性要求较高或者网络状况很好(如局域网)的情况下可以选择使用UDP协议。

Socket

常用的socket类型有2种
(1)流式socket(SOCK_STREAM)
提供可靠的,面向连接的通信流,采用TCP协议
(2)数据报socket( SOCK_DGRAM)
定义了一种无连接服务,采用UDP协议

▁▂▃▄▅▆▇█
socket编程的基本函数有socket()、bind()、listen()、accept()、send()、sendto()、recv()、recvfrom()等

■ socket():该函数用于建立一个socket连接
■bind():该函数用于将本地IP地址绑定到端口号
■listen():创建一个等待队列,在其中存放未处理的客户端连接请求
■accept():接收客户端连接请求
■connect():与服务器建立连接
■send()和recv():发送和接收数据
■sendto()和recvfrom():与send()和recv()类似,当用UDP时,可以在之前没有使用connect()的情况下,自动寻找指定地址并进行连接

在这里插入图片描述
下面是一个简单的TCP通信演练
服务器端:

import socket

# 创建实例
sk=socket.socket()
# 定义绑定ip和端口号
ip_port=("127.0.0.1",8888)
# 绑定监听
sk.bind(ip_port)
# 最大连接数
sk.listen(5)

while True:
    print("正在等待接收数据")
    # 接收连接请求
    conn,address=sk.accept()
    # 发送消息给客户端
    msg="连接成功"
    conn.send(msg.encode())

    while True:
        # 不断接收客户端信息
        data=conn.recv(1024)
        print("收到客户端信息:"+data.decode())
        # 接收到退出指令
        if data==b'exit':
            break
        # 处理客户端信息
        str_back="已经收到你的信息:"
        conn.send(str_back.encode())
        conn.send(data)

    # 主动关闭连接
    conn.close()

非阻塞服务器端:

import socketserver

class MyServer(socketserver.BaseRequestHandler):
    def setup(self):
        pass
    def handle(self):
        # 连接变量
        conn=self.request
        # 消息发送
        msg="hello"
        conn.send(msg.encode())
        while True:
            data=conn.recv(1024)
            print(data.decode())
            if data == b"exit":
                break
            # 给客户端发送回执
            str_back = "已经收到你的信息:"
            conn.send(str_back.encode())
            conn.send(data)
        conn.close()

    def finish(self):
        pass
if __name__ =="__main__":
    # 创建多线程实例
    server=socketserver.ThreadingTCPServer(("127.0.0.1",8888),MyServer)
    # 开启异步多线程,等待连接
    server.serve_forever()

ps:如果遇到xxx is not allowed to run in parallel的问题
在这里插入图片描述
可以在Run > Edit Configurations下,勾选对应文件的 Allow parallel run

客户端:

import socket

# 创建实例
client=socket.socket()
# 定义绑定ip和端口号
ip_port=("127.0.0.1",8888)
# 连接服务器
client.connect(ip_port)

while True:
    # 接收服务器信息
    data = client.recv(1024)
    print(data.decode())

    # 发送消息给服务器
    msg_input=input("请输入要发送的消息:")
    client.send(msg_input.encode())
    if msg_input =="exit":
        break

在这里插入图片描述
服务器端

import socket

sk=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
ip_port=("127.0.0.1",8888)
sk.bind(ip_port)

while True:
    data=sk.recv(1024)
    print(data.decode())

客户端:

import socket

client=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
ip_port=("127.0.0.1",8888)

while True:
    msg_input = input("请输入要发送的消息:")
    if msg_input =="exit":
        break
    client.sendto(msg_input.encode(),ip_port)
client.close()

文件发送与接收

客户端发送文件:

import socket

# 创建实例
client=socket.socket()
# 定义绑定ip和端口号
ip_port=("127.0.0.1",9999)
# 连接服务器
client.connect(ip_port)
# 文件分割上传
with open('sock_server_tcp2.py','rb') as f:
    for i in f:
        client.send(i)
        # 等待接受完成标志
        data=client.recv(1024)
        if data !=b'succeed':
            break

# 给服务器端发送结束信号
client.send('quit'.encode())

服务器端接收文件:

import socket

sk=socket.socket()
ip_port=("127.0.0.1",9999)
sk.bind(ip_port)
sk.listen(5)
while True:
    conn,address=sk.accept()
    while True:
        # 接收文件为二进制可添加模式
        with open("file","ab") as f:
            data=conn.recv(1024)
            if data==b'quit':
                print("接收完成")
                break
            f.write(data)
        # 每次接受完成之后,给发送端发送一个接收完成标志
        conn.send('succeed'.encode())
sk.close()


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值