socket

socket

socket也叫套接字,用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过套接字向网络发送出请求或者应答网络请求。

socket起源于Unix,而Unix、Linux的思想就是一切皆文件,对于文件用打开,读写,关闭模式来操作。socket就是该模式的一个实现,socket即是一种特使的文件,一些socket函数就是对其进行的操作(读写IO,打开关闭)

socket和file的区别:

file 模块是针对某个指定文件进行打开,读写,关闭

socket 模块是针对 服务器端和客户端socket进行打开,读写,关闭

 

一个简单的实例

socket server

import socket

ip_port = ('127.0.0.1',9999)    #$ 设置监听的IP地址和端口

sk = socket.socket()    #$ 实例化socket
sk.bind(ip_port)        #$ 开始监听
sk.listen(5)        #$ 设置接受最大连接数,类似线程数

while True:
    print ('server waiting...')
    conn,addr = sk.accept()    

    client_data = conn.recv(1024)    #$ 设置接收数据的字符数
    print(str(client_data,'utf8'))        #$ 打印出客户端发送过来的数据
    conn.sendall(bytes('这里是服务器端','utf8'))    #$ 发送数据到客户端

    conn.close()        #$ 关闭socket

socket client

import socket    #$ 引用socket模块
ip_port = ('127.0.0.1',9999)    #$ 设置连接的地址和端口

sk = socket.socket()    #$ 类似实例化socket
sk.connect(ip_port)        #$ 连接scoket地址和端口端口

sk.sendall(bytes('这里是客户端端','utf8'))    #$ 发送数据

server_reply = sk.recv(1024)    #$ 接收套接字字符数
print(server_reply)

sk.close()        #$ 关闭socket

 

写一个简单的web页面:

#!/usr/bin/env python3

import socket

def handle_request(client):
    buf = client.recv(1024)
    client.send(bytes("http/1.1 200 OK

",'utf8'))
    client.send(bytes("hello word",'utf8'))

def main():
    sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    sock.bind(('127.0.0.1',8080))
    sock.listen(5)

    while True:
        connection,address = sock.accept()
        handle_request(connection)
        connection.close()


if __name__ == '__main__':
    main()

 

socket方法:

sk = socket.socket(socket.AF_INET,socket.SOCK_STREAM,0)

参数一:地址簇

  • socket.AF_INET     IPV4(默认)
  • socket.AF_INET6    IPV6
  • socket.AF_UNIX     只能用于单一的Unix系统进程间通信

参数二:类型

  • socket.SOCK_STREAM        流式socket,TCP (默认)
  • socket.SOCK_DGRAD          数据报试socket UDP
  • socket.SOCK_RAW              原始套接字,普通的套接字无法处理ICMP,IGMP等网络报文,而SOCK_RAW可以,其次,SOCK_RAW也可以处理特殊的IPV4报文;此外,利用原始套接字,可以通过IP_HDRINCL套接字选项由用户构造IP头
  • socket.SOCK_RDM              是一种可靠的UDP形式,即保证数据完整,但不保证顺序即数据的正确。SOCK_RAM用来提供对原始协议的低级访问,在需要执行某些特殊操作时使用,如发送ICMP报文。SOCK_RAM通常仅限于高级用户或管理员运行的程序使用
  • socket.SOCK_SEQPACKET  可靠deepin连续数据包服务

参数三:协议

0     (默认)与特定的地址家族相关的协议,如果是0,则系统就会根据地址格式和套接类别,自动选择一个合适的协议

sk.bind(address)

将套接字绑定到地址,address地址的格式取决于地址簇。在AF_INET下,以元组(host,port)的形式表示地址。

sk.listen(backlog)

开始监听传入连接。backlog指定在拒绝连接之前,可以挂起的最大连接数

backlog等于5,表示内核已经接到的连接请求,但服务器还没有调用accept进行处理deepin连接个数最大为5,这个值不能无限大,因为要在内核中维护连接队列

sk.setblocking(bool)

是否阻塞(默认True),如果设置False,那么accept和recv时一旦无数据,则报错

sk.accept()

接受连接并返回(conn,address),其中conn是新的套接字对象,可以用来接收和发送数据。addreess是连接客户端的地址

接收TCP客户的连接(阻塞式)等待连接的到来

sk.connect(address)

同上,只不过会返回值,连接成功时返回0,连接失败时返回编码

sk.close()

关闭套接字

sk.recv(bufsize[,flag])

接受套接字的数据。数据以字符串形式返回,bufsize指定最多可以接收的数量。flag提供有关消息deepin其他信息,通常可恶意忽略

sk.recvfrom(bufsize[,flag])

与recv()类似,但是返回值是(data,address)。其中data是包含接收数据的字符串,address是发送数据的套接字地址。

sk.send(string[,flag])

将string中的数据发送到连接的套接字。返回值是要发送deepin字节数量,该数量可能小于srting的字节大小。即可能未将指定内容全部发送。

sk.sendall(string[,flag])

将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常

内部通过递归调用send,将所有内容发送出去。

sk.sendto(string[,flag],address)

将数据发送到套接字,address是形式为(ipaddr,port)的元组,指定远程地址。返回值是发送的字节数。主要用于UDP协议

sk.settimeout(timeout)

设置套接字操作的超时期,timeout是一个浮点数,单位是秒。值为None表示没有超时期。一般,超时期应该在刚创建套接字时设置,因为他们可能用于连接的操作(如client连接最多等待5s)

sk.getpeername()

返回连接套接字的远程地址。返回值通常是元组(ipaddr,port)

sk.getsockname()

返回套接字自己的地址。通常是一个元组(ipaddr,port)

sk.fileno()

套接字的文件描述符

socket.sendfile(file,offset=0,count=None)

发送文件,但目前多情况不用

 

 

代码实例:

实现client输入发送信息,server返回client输入的信息。

server代码:

import socket
ip_port = ('127.0.0.1',9998)
sk  = socket.socket()
sk.bind(ip_port)
sk.listen(5)

while True:
    print('Server is waiting ... ')
    conn,addr = sk.accept()
    client_data = conn.recv(1024)
    print(str(client_data,'utf-8'))
    conn.sendall(bytes('这是 server !','utf-8'))
    while True:
        client_data = conn.recv(1024)
        print('revv:',str(client_data,'utf8'))
        if not (client_data):break
        conn.sendall(client_data)

 

 

client端:

import socket
ip_port = ('127.0.0.1',9998)

sk = socket.socket()
sk.connect(ip_port)

sk.sendall(bytes('这是 client !','utf-8'))
server_replay = sk.recv(1024)
print(str(server_replay,'utf-8'))
while True:
    client_raw = input(':').strip()
    sk.sendall(bytes(client_raw,'utf-8'))
    server_replay = sk.recv(1024)
    print(str(server_replay,'utf-8'))
sk.close()

 

 

 

实现一个简单的聊天功能:

server端:

import socket
ip_port = ('127.0.0.1',9998)

sk = socket.socket()
sk.connect(ip_port)

sk.sendall(bytes('这是 client !','utf-8'))
server_replay = sk.recv(1024)
print(str(server_replay,'utf-8'))
while True:
    client_raw = input('>> ').strip()
    sk.sendall(bytes(client_raw,'utf-8'))
    server_replay = sk.recv(1024)
    print('server:',str(server_replay,'utf-8'))
sk.close()

 

client端:

import socket
ip_port = ('127.0.0.1',9998)

sk = socket.socket()
sk.connect(ip_port)

sk.sendall(bytes('这是 client !','utf-8'))
server_replay = sk.recv(1024)
print(str(server_replay,'utf-8'))
while True:
    client_raw = input(':').strip()
    sk.sendall(bytes(client_raw,'utf-8'))
    server_replay = sk.recv(1024)
    print(str(server_replay,'utf-8'))
sk.close()
原文地址:https://www.cnblogs.com/binges/p/5259085.html