首页 > 编程语言 >Python实验:Socket编程

Python实验:Socket编程

时间:2023-11-08 22:36:36浏览次数:40  
标签:Socket Python 编程 question TCP server client 客户端 socket

实验六 Socket 编程

一、实验目标:

了解TCP协议原理、标准库socket 的用法、熟悉Socket 编程。

1.TCP协议原理:

TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于流的协议,用于在计算机网络中传输数据。它是互联网协议套件中的一部分,通常与IP(Internet Protocol,互联网协议)一起使用,形成TCP/IP协议栈。

  1. 面向连接:TCP是一种面向连接的协议,这意味着在数据传输之前需要在通信的两端建立连接。建立连接的过程包括三次握手,确保双方都能够正确通信。
  2. 可靠性:TCP提供可靠的数据传输。它使用序号和确认机制来确保数据的可靠传输。每个数据包都有一个唯一的序号,接收端会发送确认来告诉发送端已成功接收数据。如果发送端没有收到确认,它将重传数据,直到确认被接收。
  3. 流控制:TCP使用流控制机制来控制数据的发送速率,以确保接收端不会被过多的数据淹没。这是通过TCP窗口大小来实现的,接收端告诉发送端它可以接收多少数据,以避免数据丢失或过载。
  4. 拥塞控制:TCP也具有拥塞控制机制,用于防止网络拥塞。它使用拥塞窗口来限制数据发送速率,以适应网络的容量,避免过多的数据导致拥塞。
  5. 有序数据传输:TCP保证数据包的有序传输。即使数据包在传输过程中乱序到达,接收端会按照正确的顺序将它们重新排序。
  6. 双工通信:TCP支持全双工通信,这意味着双方可以同时发送和接收数据,而不需要等待对方的响应。
  7. 数据分段:TCP将数据分成适当的数据段,并在每个数据段中添加头部信息,包括序号、确认号、标志位等,以便进行数据传输和控制。
  8. 错误检测和纠正:TCP包含校验和机制,用于检测传输过程中的错误。如果数据包被损坏,它将被丢弃,要求重传。

2.标准库socket的用法

​ 1.创建一个TCP服务器套接器

import socket

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # 使用IPv4和TCP协议
server_socket.bind(("0.0.0.0", 8888))  # 绑定套接字到指定的端口
server_socket.listen(5)  # 开始监听客户端连接,设置连接队列的大小为5

​ 2.创建一个TCP客户端套接字

import socket

# 创建一个TCP客户端套接字
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 连接到服务器
client_socket.connect(("server_ip", 8888))

​ 3.接受客户端连接和处理

import socket

# 创建一个TCP服务器端套接字
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(("0.0.0.0", 8888)
server_socket.listen(5)

# 接受客户端连接
client_socket, client_address = server_socket.accept()

# 处理客户端请求
data = client_socket.recv(1024)
client_socket.send("Hello, Client!".encode('utf-8'))

# 关闭套接字连接
client_socket.close()

​ 4.发送和接收数据

import socket

# 创建一个TCP客户端套接字
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(("server_ip", 8888))

# 发送数据到服务器
client_socket.send("Hello, Server!".encode('utf-8'))

# 从服务器接收数据
data = client_socket.recv(1024)
print(data.decode('utf-8'))

# 关闭客户端套接字连接
client_socket.close()

二、实验内容:

(1) 使用TCP协议实现智能聊天机器人。编写聊天程序的服务端代码和客户端代码。完成后,先启动服务端代码,然后启动客户端程序用输入问题,服务端可以返回相应的答案。要求服务端代码具有一定的智能,能够根据不完整的问题识别客户端真正要问的问题。(问题和答案是预先定义好的)要求支持多线程。

服务端代码:

import socket
import threading  # 用于处理多个客户端连接的多线程支持
import re
question_anwers = {
    '你好': "你好,有什么可以帮助你的吗?",
    "现在几点了":"现在20:46",
    "你叫什么名字": "我叫chatGBT",
    "你会做什么": "我会回答一些基本问题",
    "再见": "再见,愚蠢的人类",
    "天气查询": "今天最高温度达到27℃",
    "时间查询": "请看右下角"
}


def identify_intension(question):
    question = question.lower()
    if re.search("天气",question):
        return "天气查询"
    if re.search("时间",question):
        return "时间查询"
    if re.search("你会什么",question):
        return "你会做什么"
    if re.search("你叫什么",question):
        return "你叫什么名字"
    if re.search("你是",question):
        return "你叫什么名字"
    if re.search("几点了",question):
        return "现在几点了"
    for key in question_anwers: #模糊匹配
        if key in question:
            return key


def handle_client(client_socket):
    while True:
        question = client_socket.recv(1024).decode('utf-8')
        if not question:
            break
        intension = identify_intension(question)
        if intension in question_anwers:
            answer = question_anwers[intension]
        else:
            answer="我不知道怎么回答这个问题"
        client_socket.send(answer.encode('utf-8'))
    client_socket.close()




def main():
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # 创建服务器套接字,使用IPv4协议和TCP协议
    server.bind(("0.0.0.0", 8888))
    server.listen(5)
    print("服务器已启动,等待连接……")
    while True:
        client_socket, addr = server.accept()
        print("接收到的连接来自 %s:%s" % (addr[0], addr[1]))
        client_handler = threading.Thread(target=handle_client, args=(client_socket,))
        client_handler.start()


if __name__ == '__main__':
    main()

客户端代码:

import socket
def main():
    client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    client.connect(("127.0.0.1",8888))
    while True:
        question = input("请输入你的问题(或输入exit以退出)")
        if question.lower()=='exit':
            break
        client.send(question.encode('utf-8'))
        response = client.recv(1024).decode('utf-8')
        print(response)
    client.close()
if __name__=="__main__":
    main()

(2) 使用UDP协议打造在线时间服务器。服务端监听特定的端口,如果收到客户端发来的请求就把服务器上的当前时间发给客户端,而客户端收到时间之后立刻打印输出。

服务端:

import socket
import time
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_address = ("0.0.0.0", 8888)
server_socket.bind(server_address)

print("时间服务器已启动,等待请求...")

while True:
    data, client_address = server_socket.recvfrom(1024)
    if data.decode('utf-8') == "时间":
        current_time = time.ctime()
        server_socket.sendto(current_time.encode('utf-8'), client_address)

客户端:

import socket

client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_address = ("127.0.0.1", 8888)
request = "时间"
client_socket.sendto(request.encode('utf-8'), server_address)
# 接收服务器的时间响应
data, server_address = client_socket.recvfrom(1024)
print("服务器时间:", data.decode('utf-8'))

(3) 使用socketserver模块建立基于tcp协议通信的服务,收到客户端发来的英文字符串之后,将其变为大写发回客户端。

服务端代码:

import socketserver


class MyTCPhandler(socketserver.BaseRequestHandler):  # 定义一个自定义的处理器类
    def handle(self):
        while True:  # 持续接收
            try:
                data = self.request.recv(1024)  # 从客户端接受数据
                print('收到客户端的消息: ', data)  # 打印接收的数据
                self.request.send(data.upper())  # 转换成大写发送到客户端
            except ConnectionResetError:  # 如果连接异常,就退出
                break
        self.request.close()


if __name__ == '__main__':
    server = socketserver.ThreadingTCPServer(('127.0.0.1', 8888), MyTCPhandler)
    print("服务端已启动")
    server.serve_forever()

客户端代码:

from socket import *

client = socket(AF_INET, SOCK_STREAM)
client.connect(('127.0.0.1', 8888))
# 通信循环
print("客户端已启动,输入exit()退出")
while True:

    data = input("请输入要发送的数据:")
    if data == 'exit()':
        break
    client.send(data.encode('utf-8'))
    Data = client.recv(1024)
    print(Data)
client.close()

(4) 编写代码对网络上的ip地址进行端口扫描,收集“ip+开放端口”信息。进一步的,尝试了解和使用流行的网络扫描工具进行扫描,如zmap,nmap,并写出使用过程和扫描结果。

python实现:

import socket


def scan_port(ip):
    for port in range(1, 1000):
        p = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        p.settimeout(0.1)
        respond = p.connect_ex((ip, port))
        if respond == 0:
            print(f"主机{ip},端口{port}已开放")
        p.close()
    print("扫描完毕")


target_host = input("请输入ip:")
scan_port(target_host)

尝试扫描 baidu.com
先ping一下baidu.com

image.png

然后进行端口扫描:
image.png

Nmap扫描:
尝试扫描 github.com

image.png

标签:Socket,Python,编程,question,TCP,server,client,客户端,socket
From: https://www.cnblogs.com/Smera1d0/p/17818491.html

相关文章

  • 练手python脚本分享
    分享一个最近练手的脚本,没什么实际意义,纯粹就是练手用的,最近准备把python拿出来再练练,所以随意找了点东西研究下,脚本里主要用到了ttkbootstrap来做GUI,以及非常非常基础的azurepython的SDKimportdatetimeimportttkbootstrapasttkfromttkbootstrap.constantsimport*fromt......
  • Python中的列表和元组:添加、修改和删除元素的技巧
    在Python中,列表(List)和元组(Tuple)都是用于存储数据的集合类型。虽然它们在某些方面相似,例如都可以存储各种类型的数据,但它们也有一些重要的区别,比如可变性。列表是可变的,意味着我们可以更改、添加或删除列表中的元素,而元组是不可变的,一旦它被创建,就不能更改。在这篇文章中,我们将详细......
  • Python 数据库应用教程:安装 MySQL 及使用 MySQL Connector
    Python可以用于数据库应用程序。其中最流行的数据库之一是MySQL。MySQL数据库为了能够在本教程中尝试代码示例,您应该在计算机上安装MySQL。您可以在MySQL官方网站下载MySQL数据库。安装MySQL驱动程序Python需要一个MySQL驱动程序来访问MySQL数据库。在本教程中,我们将使用"......
  • 以多个文件的名称为基准复制其他路径下的同名文件:Python实现
      本文介绍基于Python语言,针对一个文件夹下大量的Excel表格文件,基于其中每一个文件的名称,从另一个文件夹中找到与这一文件夹中文件同名的文件,并将找到的同名文件复制到第三个文件夹中的方法。  首先,我们来明确一下本文的具体需求。现有一个文件夹,其中有大量的Excel表格文件(在......
  • Python如何将日志输入到文件里
    要将日志输出到文件中,你可以使用Python标准库的`logging`模块。以下是一个示例,演示如何配置`logging`模块来记录日志到文件:```pythonimportlogging#配置日志log_file='/path/to/your/logfile.log'logging.basicConfig(  filename=log_file,  level=logging.DEBU......
  • Python 数据库应用教程:安装 MySQL 及使用 MySQL Connector
    Python可以用于数据库应用程序。其中最流行的数据库之一是MySQL。MySQL数据库为了能够在本教程中尝试代码示例,您应该在计算机上安装MySQL。您可以在MySQL官方网站下载MySQL数据库。安装MySQL驱动程序Python需要一个MySQL驱动程序来访问MySQL数据库。在本教程中,我们将使用......
  • 编程冷知识
    编程冷知识qt中只修改宏,不修改其它东西,编译运行还会时原先的结果,必须手动强制重新编译。c++中ostream删除了拷贝构造和复制构造,是为了避免两个ostream同时向一个输出流输出数据。如果想使用std::cout将内容输出到终端,可以写成ostream&os=std::cout;如果想将信息记录到文......
  • python循环遍历字典: title_content_list.append([key, value])print(ti
    示例示例Python循环遍历字典的方法有以下几种:使用for...in循环:Python循环遍历字典的方法有以下几种:1.使用for...in循环:pythondict={'name':'Tom','age':20,'gender':'male'}#遍历所有的键forkeyindict:print(key)#遍历所有的值forvalueindict.values......
  • python语言合法命名规则:my_first_python_program
    示例示例Python语言合法命名规则:命名只能使用字母、数字和下划线,不能使用其他符号;Python语言合法命名规则:1.命名只能使用字母、数字和下划线,不能使用其他符号;2.不能以数字开头;3.不能使用Python关键字;4.命名应该有意义,尽量不要使用缩写;5.命名应该具有可读性,尽量使用驼峰命名法,......
  • Python调用C动态库并通过bytes传参
    通过Python内建库ctypes调用C语言。#!/usr/bin/python3#file:bytes_test.pyimportctypesasctimportos#编译C程序为动态库os.system("gcc-fpic-sharedbytes_test.c-obytes_test.dll")#加载动态库clib=ct.CDLL("./bytes_test.dll")#分配内存src=b......