首页 > 代码库 > day7 socket网络编程基础

day7 socket网络编程基础

Socket

Socket是什么?

    下面来看一下网络的传输过程:

    技术分享

    上面图片显示了网络传输的基本过程,传输是通过底层实现的,有很多底层,我们写传输过程的时候,要知道所有的过程那就太复杂了,socket为我们封装了底层的传输流程,让我们直接可以在socket上直接实现数据交换。

    socket本质:对底层网络协议的封装。

    socket实现数据的发送和接收,通过什么建立连接呢?下面看一幅简单的图片:

    技术分享  

    在计算机上,我们运行了很多线程,我们如何实现数据的定向交换呢?如何实现客户端和服务器的连接呢?连接我们可以通过IP地址进行连接,连接上之后发送给那个程序呢?这时候我们就要通过port(端口号)进行指明,因为实现连接的过程是通过IP+端口号(port)进行连接。

    客户端

 

import socket
while True:
    s = socket.socket()
    ‘‘‘生成一个socket连接‘‘‘
    s.connect(("localhost",6970))   #建立连接,连接本地,端口号是6969端口

    message = input("请输入您要发送的信息:").encode(utf-8)
    if message == "quit":
        break
    s.sendall(message)   #python3上只能传输二进制字节
    data = s.recv(1024)      #接收服务器端传来的内容
    print(data)

s.close()   #关闭连接

 

    上面代码就是客户端,通过客户端发送数据到服务器,实现交互,客户端加上了一个while循环,能够实现多次交互,我们知道,正常情况下,交互一次就退出了,通过While循环,让客户端不停的产生新的连接,就能不断与客户端进行数据交换。

    下面是客户算发送的数据,只能以字符的形式进行发送,所以发送的是字符,汉字看不到,进行转换了。而且不知道为什么,输入空之后,客户端没有响应,静止不动了:

请输入您要发送的信息:dasfda
bdasfda
请输入您要发送的信息:不能发送汉字吗
b\xe4\xb8\x8d\xe8\x83\xbd\xe5\x8f\x91\xe9\x80\x81\xe6\xb1\x89\xe5\xad\x97\xe5\x90\x97
请输入您要发送的信息:放大法是否对
b\xe6\x94\xbe\xe5\xa4\xa7\xe6\xb3\x95\xe6\x98\xaf\xe5\x90\xa6\xe5\xaf\xb9
请输入您要发送的信息:dfafdas
bdfafdas
请输入您要发送的信息:dfasdfa
bdfasdfa
请输入您要发送的信息:dfasfd
bdfasfd
请输入您要发送的信息:afdasdfas
fbafdasdfas
请输入您要发送的信息:dasfda
bfdasfda
请输入您要发送的信息:dfa
fdabdfa
请输入您要发送的信息:
bfda
请输入您要发送的信息:afasfda
bafasfda
请输入您要发送的信息:afdasfd
bafdasfd
请输入您要发送的信息:afdasdfa
bafdasdfa
请输入您要发送的信息:

服务器

 

import socket

‘‘‘生成socket实例‘‘‘
s = socket.socket()
s.bind(("localhost",6970))    #绑定本地IP和6969端口号
s.listen(10)     #监听客户端发送的信息,一旦有客户端发送过来连接,就接收,现在是等待状态,防止堵塞
print("连接建立完毕,正在等待数据.......")
while True:
    conn,addr = s.accept()    #接收数据,accept()会接收两个数据,一个是连接conn,一个是地址addr(IP和端口号)
    print("Addr:",addr)
    data = conn.recv(1024)   #通过连接接收数据
    print(data)
    conn.send(data)      #发送数据,把接收到的信息发送

conn.close()
s.close()

 

     上面是服务器的代码,我们也使用了一个循环,让服务器一直挂着,等待客户端发送数据,不停的接收:

    下面是服务器接收的数据:

连接建立完毕,正在等待数据.......
Addr: (127.0.0.1, 51924)
bdasfda
Addr: (127.0.0.1, 51926)
b\xe4\xb8\x8d\xe8\x83\xbd\xe5\x8f\x91\xe9\x80\x81\xe6\xb1\x89\xe5\xad\x97\xe5\x90\x97
Addr: (127.0.0.1, 51928)
b\xe6\x94\xbe\xe5\xa4\xa7\xe6\xb3\x95\xe6\x98\xaf\xe5\x90\xa6\xe5\xaf\xb9
Addr: (127.0.0.1, 51930)
bdfafdas
Addr: (127.0.0.1, 51932)
bdfasdfa
Addr: (127.0.0.1, 51934)
bdfasfd
Addr: (127.0.0.1, 51936)
bafdasdfas
Addr: (127.0.0.1, 51938)
bfdasfda
Addr: (127.0.0.1, 51940)
bdfa
Addr: (127.0.0.1, 51942)
bfda
Addr: (127.0.0.1, 51944)
bafasfda
Addr: (127.0.0.1, 51946)
bafdasfd
Addr: (127.0.0.1, 51948)
bafdasdfa
Addr: (127.0.0.1, 51950)

    可以看出,数据进行了多次的交互,并且接收了数据,是以字符编码形式进行接收的。

客户端
import socket

client = socket.socket()    #声明socket类型,同时生成socket连接对象
client.connect(("localhost",6969))

client.send("我要下载A片".encode("utf-8"))     #在python3中只能发送字节
data = client.recv(1024)    #默认接收数据的大小,定义1024个字节
print("recv:",data.decode())

client.close()    #关闭连接


服务器
#服务器端
import socket

server = socket.socket()
server.bind(("localhost",6969))   #绑定要监听端口
server.listen()    #监听

print("我要开始等电话了")
conn,addr = server.accept()    #等待接收,conn对方的连接,addr对方的地址,接收会接收到一个IP编号和地址
#conn就是客户端连过来而在服务器端为其生成的一个连接实例
print(conn,addr)

print("电话来了")
data = conn.recv(1024)    #接收的数据大小,不能直接调用server接收,打电话新的进来,可以切换
print("recv:",data)
conn.send(data.upper())

server.close()

    下面来看一个循环的代码:

#服务器端
import socket

server = socket.socket()
server.bind(("localhost",6969))   #绑定要监听端口
server.listen()    #监听

print("我要开始等电话了")
while True:
    conn,addr = server.accept()    #等待接收,conn对方的连接,addr对方的地址,接收会接收到一个IP编号和地址
    #conn就是客户端连过来而在服务器端为其生成的一个连接实例
    print(conn,addr)

    print("电话来了")
    data = conn.recv(1024)    #接收的数据大小,不能直接调用server接收,打电话新的进来,可以切换
    print("recv:",data)
    conn.send(data.upper())

server.close()

    首先启动服务器端,等待客户端发送数据:

    客户端:

import socket

client = socket.socket()    #声明socket类型,同时生成socket连接对象
client.connect(("localhost",6969))

while True:
    msg = input(">>:").strip()      #输入空会卡主,我们知道,QQ也是不允许用户输入空的,会提示输入为空
    client.send(msg.encode("utf-8"))     #在python3中只能发送字节
    data = client.recv(1024)    #默认接收数据的大小,定义1024个字节
    print("recv:",data.decode())

client.close()    #关闭连接

    客户端输入:

    >>:我
  recv: 我
  >>:要

    上面可以看出,客户端输入第一次正常,第二次卡住了,只能进行一次通讯,说明客户端的实现一次通讯之后终止了。

    服务端接收:

    我要开始等电话了
  <socket.socket fd=4, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=(‘127.0.0.1‘, 6969), raddr=     (‘127.0.0.1‘, 58460)> (‘127.0.0.1‘, 58460)
  电话来了
  recv: b‘\xe6\x88\x91‘

    可以看出,服务器端第一次接收数据之后,也卡住了,服务器端卡主是由于没有新的连接进来,连接并没有终端,而只是客户端自己断开,找不到新的连接挂在哪里。

    下面来修改客户端代码:

   

   

 

   

 

 

 

 

 

 

 

 

 

请输入您要发送的信息:dasfda
b‘dasfda‘
请输入您要发送的信息:不能发送汉字吗
b‘\xe4\xb8\x8d\xe8\x83\xbd\xe5\x8f\x91\xe9\x80\x81\xe6\xb1\x89\xe5\xad\x97\xe5\x90\x97‘
请输入您要发送的信息:放大法是否对
b‘\xe6\x94\xbe\xe5\xa4\xa7\xe6\xb3\x95\xe6\x98\xaf\xe5\x90\xa6\xe5\xaf\xb9‘
请输入您要发送的信息:dfafdas
b‘dfafdas‘
请输入您要发送的信息:dfasdfa
b‘dfasdfa‘
请输入您要发送的信息:dfasfd
b‘dfasfd‘
请输入您要发送的信息:afdasdfas
fb‘afdasdfas‘
请输入您要发送的信息:dasfda
b‘fdasfda‘
请输入您要发送的信息:dfa
fdab‘dfa‘
请输入您要发送的信息:
b‘fda‘
请输入您要发送的信息:afasfda
b‘afasfda‘
请输入您要发送的信息:afdasfd
b‘afdasfd‘
请输入您要发送的信息:afdasdfa
b‘afdasdfa‘
请输入您要发送的信息:

day7 socket网络编程基础