利用Python创建最基本的socket实现服务器和客户端连接和信息传输

socket库调用

import socket

服务端socket生成

import sys
try:
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 防止socket server重启后端口被占用(socket.error: [Errno 98] Address already in use)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    s.bind(('127.0.0.1', 6666))
    s.listen(10)
except socket.error as msg:
    print(msg)
    sys.exit(1)
print('Waiting connection...')

代码解释:

socket.socket() 生成socket实例,参数为socket形式

s.setsockopt(socket层,想要设置的选项,设置的值) socket对象定义的方法,用于设定该套接字的相关参数

s.bind( ( ip(string),port(int) ) ) socket对象绑定到一个地址,注意该地址用元组进行标识是本地服务器地址,相当于为服务端创建socket

s.listen(最大连接数量) 设置该socket的最大连接数量,表示内核已经接到了连接请求,但服务器还没有调用accept进行处理的连接个数,这个值不能无限大,因为要在内核中维护连接队列

进入循环进行连接

import threading
while 1:
    conn, addr = s.accept()
    t = threading.Thread(target=deal_data, args=(conn, addr))
    t.start()

while 1进入循环,即每当accept一个连接,就循环一次

s.accept() 阻塞式的连接,在未建立连接前,进程会在这一步阻塞

返回值conn代表新的套接字,对应客户端和服务端间的连接

addr为字符串,表示客户端的地址,用于向服务端传递连接信息

threading.Threadtarget(线程的函数名),args(向线程内函数传递参数,元组形式)) 每当建立一个连接,就开一个线程

处理服务端接受的数据

import sys
def deal_data(conn, addr):
    print('Accept new connection from {0}'.format(addr))
    conn.send(('Hi, Welcome to the server!').encode())#send内容形式一
    while 1:
        data = conn.recv(1024)
        print('{0} client send data is {1}'.format(addr, data.decode()))
        time.sleep(1)
        if data == 'exit' or not data:
            print('{0} connection close'.format(addr))
            conn.send(bytes('Connection closed!'),'UTF-8')#send内容形式二
            break
        conn.send(bytes('Hello, {0}'.format(data),"UTF-8"))
    conn.close()

conn.send(信息) 通过在客户端和服务端间的套接字进行传输,注意信息需要经过编码成二进制

while 1进入循环,每从客户端接收到一个信息,就循环一次

conn.recv(信息最大大小)  对应bytes,同样是阻塞式的,未接受到之前不会继续

返回值data代表接受的信息,是编码后的,需要解码

data=‘exit’时,服务端推出while的死循环,相当于互动结束

conn.close() 关闭客户端和服务端间套接字

注意到服务端一共有两个套接字,sc

s是服务端本地的套接字,用于和本机地址绑定并监听请求,利用accept()创建服务端和客户端间一对一的套接字。

c就是用于连接的套接字,主要承担通信,并具有明显的生命周期。

客户端

try:
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(('127.0.0.1', 6666))
except socket.error as msg:
    print(msg)
    sys.exit(1)
print(s.recv(1024))  # 目的在于接受:Accept new connection from (...
while 1:
    data = input('please input work: ').encode()
    s.send(data)
    print('aa', s.recv(1024))
    if data == 'exit':
        break
s.close()

socket.socket() 创建套接字对象

s.connect(用元组表示的地址) 利用connect方法绑定的套接字,说明是用于连接的,故有明显生命周期

 

posted @ 2020-05-11 09:56  neumy  阅读(712)  评论(0编辑  收藏  举报