Python基础入门——网络编程(基础概念 、Socket、TCP、UDP)

1、网络编程两个主要的问题:

      1、如何准确的定位网络上一台或多台主机(IP层进行定位)

       2、找到主机后如何可靠高效的进行数据传输 (TCP层进行数据传输)

2、TCP/IP协议是一个协议集合

      (ethernet 以太网,也就是一般所说的拉网线所用的网络接口协议)

3、Socket编程

网络通信三件套:IP地址 端口 协议

"""打印设备名和IPv4地址"""
host_name = socket.gethostname()
print("Host name : %s" % host_name) # 对应计算机名

print(socket.gethostbyname('localhost'))
print(socket.gethostbyname_ex('localhost'))

输出:
Host name : O87VDZIU6H0596N
127.0.0.1
('O87VDZIU6H0596N', [], ['127.0.0.1'])

localhost意为本地主机,指这台计算机,是给回路网络接口的标准主机名,对应的IP地址为127.0.0.1

"""获取远程设备的IP地址"""
def get_remote_machine_info():
    remote_host ='qq.com'
    try:
        print("IP address: %s" %socket.gethostbyname(remote_host))
        print(socket.gethostbyname_ex(remote_host))
    except socket.error as err_msg:
        print("%s :%s"%(remote_host,err_msg))

get_remote_machine_info()

输出:
IP address: 58.250.137.36
('qq.com', [], ['58.250.137.36', '125.39.52.26', '58.247.214.47'])
"""通过指定的端口和协议找到服务名"""
def find_service_name():
    protocolname = 'tcp'
    for port in [80,25]:
        print("Port: %s => service name: %s " %(port,socket.getservbyport(port,protocolname)))
    print("Port: %s => service name: %s " % (53, socket.getservbyport(53, 'udp')))

find_service_name()

输出:
Port: 80 => service name: http 
Port: 25 => service name: smtp 
Port: 53 => service name: domain 
"""IP地址转换"""
def convert_ipv4_address():
    for ip_addr in ['127.0.0.1','192.168.0.1']:
        """inet_aton一个字符串IP地址转换为一个32位的网络序列IP地址"""
        """inet_ntoa一个32位的网络序列IP地址转换为一个字符串IP"""
        packed_ip_addr = socket.inet_aton(ip_addr)
        unpacked_ip_addr = socket.inet_ntoa(packed_ip_addr)
        """hexlify作用是返回的二进制数据的十六进制表示"""
        print("IP address: %s => packed: %s,unpacked: %s"%(ip_addr,hexlify(packed_ip_addr),unpacked_ip_addr))
        print("IP address: %s => packed: %s,unpacked: %s" % (ip_addr, packed_ip_addr, unpacked_ip_addr))

convert_ipv4_address()

输出:
IP address: 127.0.0.1 => packed: b'7f000001',unpacked: 127.0.0.1
IP address: 127.0.0.1 => packed: b'\x7f\x00\x00\x01',unpacked: 127.0.0.1
IP address: 192.168.0.1 => packed: b'c0a80001',unpacked: 192.168.0.1
IP address: 192.168.0.1 => packed: b'\xc0\xa8\x00\x01',unpacked: 192.168.0.1
"""ntp"""
def print_time():
    ntp_client = ntplib.NTPClient()
    response = ntp_client.request('cn.ntp.org.cn')
    """访问对象中的tx_time成员,即是server的发射时间"""
    """ctime()函数把一个时间戳(按秒计算的浮点数)转化为time.asctime()的形式"""
    print(ctime(response.tx_time))

print_time()

输出:
Wed Jan  8 21:15:05 2020

"""把套接字改成阻塞或非阻塞模式"""
import socket

def test_socket_modes():
    s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

    #1 阻塞模式
    #0 非阻塞模式
    s.setblocking(1)
    s.settimeout(0.5)
    s.bind(("127.0.0.1",0)) #输入元组
    socket_address = s.getsockname()
    print("Server launched on socket; %s" % str(socket_address))
    while(1):
        s.listen(1)

test_socket_modes()

3.1 Echo Server/Client

## echo_server.py 文件 ##
import socket
import sys

host = 'localhost'
backlog = 50

def echo_server(port):
    """A simple echo server"""
    # create a TCP socket
    sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    #enable reuse address/port
    sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
    server_address = (host,port)
    print("Starting up echo server on  %s port %s" %server_address)
    sock.bind(server_address)
    #listen to clients, backlog argument specifies the max no. of queued connections
    sock.listen(backlog)
    server, address = sock.accept()
    while True:
        print("Waiting to receive message from client")
        #client,address = sock.accept()
        #server,address = sock.accept()
        #data = client.recv(2048)#此处的recv是指从client接收的数据,不要被这里的client变量误导了
        data = server.recv(2048)
        if data:
            print("Data: %s" % data)
            #client.send(data)
            server.send(data)
            print("Send %s bytes back to %s" % (data,address))
            if data == "bye":
                print("echo server stop")
                #break
                server.close()
        #client.close()
        #server.close()
echo_server(9999)
## echo_client.py ##
import socket
import sys

host = 'localhost'

def echo_client(port):
    """A simple echo client"""
    sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    server_address = (host,port)
    print("Conecting to %s port %s" %server_address)
    sock.connect(server_address)

    try:
        while(True):
            #message = b"bye"
            message = input()
            message = message.encode('utf8')#注意:这一行写到下一行里就不行,而且这样就是生成byte类型
            print("Sending: %s" % message)
            sock.sendall(message)

            amount_received = 0
            amount_expected = len(message)
            while amount_received <amount_expected:
                data = sock.recv(2048)
                amount_received += len(data)
                print("Received: %s" % data)
    except socket.error as e:
        print("Socket error: %s" % str(e))
    except Exception as e:
        print("Other exception: %s" % str(e))
    finally:
        print("Closing connection to the server")
        sock.close()

echo_client(9999)

3.2  File Server/Client

## file_server.py  ##

import socket
import sys

host = 'localhost'
backlog = 50

def file_server(port):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_address = (host, port)
    print("Starting up file server on  %s port %s" % server_address)
    sock.bind(server_address)
    sock.listen(backlog)
    while True:
        print("Waiting to receive message from client")
        server, address = sock.accept()
        data = server.recv(2048)
        if data:
            print('receive file')
            with open('data/ft_test_server.txt','w') as fp:
                fp.write(data.decode('utf8'))
            break
        server.close()
    print('server closed')
file_server(9999)
## file_client.py ##

import socket
import data_file
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server_address = ('localhost',9999)
print("Conecting to %s port %s" % server_address)
sock.connect(server_address)

with open(data_file.datafile,'r') as fp:
    sock.sendall(fp.read().encode('utf8'))
    print('sending file')
## data_file.py ##

import os
datafile = 'data/ft_test-client.txt'
if not os.path.exists('data'):
    os.mkdir('data')
with open(datafile,'w') as fp:
    fp.writelines([
        'Over hil,over dale,',
        'Thorough bush,thorough brier,',
        'Over park,over pale,',
        'Thorough flood, thorough fire!'
        'Over hil,over dale,',
        'Thorough bush,thorough brier,',
        'Over park,over pale,',
        'Thorough flood, thorough fire!'
        'Over hil,over dale,',
        'Thorough bush,thorough brier,',
        'Over park,over pale,',
        'Thorough flood, thorough fire!',])

3.3 TCP server

from socketserver import TCPServer,BaseRequestHandler
class MyBaseRequestHandlerr(BaseRequestHandler):
    """
    从BaseRequestHandler继承,并重写handle方法
    """
    def handle(self):
        while True:
            try:
                data = self.request.recv.strip()#strip() 方法用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列
                print("receive from (%r):%r" %(self.client_address,data))
                self.request.sendall(data.upper())
                if data == "y":
                    print('server exit')
                    break
            except:
                break
host = '0.0.0.0'
port = 9997
addr = (host,port)
server = TCPServer(addr,MyBaseRequestHandlerr)
print('server is started')
server.serve_forever()
# 在套接字服务器程序中使用 ThreadingMixIn

import os
import socket
import threading
import socketserver

SERVER_HOST = 'localhost'
SERVER_PORT = 0
BUF_SIZE = 1024

def client(ip,port,message):
    """A client to test threading mixin server"""
    sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    sock.connect((ip,port))
    try:
        sock.sendall(message)
        response = sock.recv(BUF_SIZE)
        print("Client received: %s" % response)
    finally:
        sock.close()

class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
    """A example of threaded TCP request handler"""
    def handle(self):
        data = self.request.recv(BUF_SIZE)
        current_thread = threading.current_thread()
        response = '%s : %s' %(current_thread.name,data)
        self.request.send(response.encode('utf8'))

class ThreadedTCPServer(socketserver.ThreadingMixIn,socketserver.TCPServer):# 利用多继承,继承ThreadingMixIn 和 TCPServer 类
    pass

def main():
    server = ThreadedTCPServer((SERVER_HOST,SERVER_PORT),ThreadedTCPRequestHandler)
    ip,port = server.server_address
    print(ip,port,'server')
    server_thread = threading.Thread(target=server.serve_forever)
    server_thread.daemon = True
    server_thread.start()
    print('server loop runing thread : %s '% server_thread.name)

    input('start client next ?')

    client(ip,port,b'hello from client 1')
    client(ip,port,b'hello from client 2')
    client(ip,port,b'hello from client 3')

    server.shutdown()

main()

# 在套接字服务器程序中使用 ForkingMixIn
import os
import socket
import threading
import socketserver

SERVER_HOST = 'localhost'
SERVER_PORT = 0
BUF_SIZE = 1024
ECHO_MSG = 'hello echo server !'

class ForkingClient():

    def __int__(self,ip,port):
        self.sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        self.sock.connect((ip,port))

    def run(self):
        current_process_id = os.getpid()
        print('PID %s sending echo message to the server %s'%(current_process_id,ECHO_MSG))
        send_data_length = self.sock.send(ECHO_MSG.encode('utf8'))
        print('Send: %d characters,so far ... '% send_data_length)

        response = self.sock.recv(BUF_SIZE)
        print("PID %s received: %s " %(current_process_id,response[5:]))

    def shutdown(self):
        self.sock.close()

class ForkingServerRequestHandler(socketserver.BaseRequestHandler):
    def handle(self):
        data = self.request.recv(BUF_SIZE)
        current_process_id = os.getpid()
        response = '%s : %s'%(current_process_id,data)
        print('server sending response [current_process_id: data] = %s'% response)
        self.request.send(response.encode('uft8'))
        return

class ForkingServer(socketserver.ForkingMixIn,socketserver.TCPServer):
    pass

def main():
    server = ForkingServer((SERVER_HOST,SERVER_PORT),ForkingServerRequestHandler)
    ip, port = server.server_address
    print(ip, port, 'server')
    server_thread = threading.Thread(target=server.serve_forever)
    server_thread.daemon = True
    server_thread.start()
    print('server loop runing thread : %s ' % os.getpid())

    client1 = ForkingClient(ip,port)
    client1.run()
    client2 = ForkingClient(ip,port)
    client2.run()
    server.shutdown()
    client1.shutdown()

    server.socket.close()


main()

3.4 UDP server

## UDP_server.py ##

import socket

address = ('127.0.0.1',31500)
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
s.bind(address)

while True:
    data,addr = s.recvfrom(2048)
    if not data:
        print('client has exist')
        break
    if data:
        if data == 'exit':
            print(' exiting server')
            break
s.close()
## UDP_client.py ##
import socket

address = ('127.0.0.1',31500)
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

while True:
    msg = input('message to send:')
    if not msg:
        break
    s.sendto(msg.encode('utf8'),address)
    if msg == 'exit':
        print('client exit')
        break
s.close()

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值