首页 > 技术文章 > Socket网络编程

remixnameless 2020-08-07 18:06 原文

Socket编程-简介

Socket本质是编程接口(API): Socket 是对 TCP/IP 协议的封装,Socket 只是个编程接口不是协议,通过 Socket 我们才能使用 TCP/IP 协议簇(程序员层面)

TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口;HTTP是轿车,提供了封装或者显示数据的具体形式;Socket是发动机,提供了网络通信的能力
最重要的是,Socket是面向客户/服务器模型而设计的,针对客户和服务器程序提供不同的Socket系统调用
套接字之间的连接过程可以分为三个步骤:服务器监听,客户端请求,连接确认

创建Socket

import socket
#导入套接字模块
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#s此时是一个socket对象,拥有发送和接收网络数据的功能
#该函数带有两个参数(参数必须写)
#AF_INET(ipv4协议⽤于 Internet 进程间通信) 
#套接字类型:
#SOCK_STREAM(流式套接字, ⽤于TCP 协议)
#SOCK_DGRAM(数据报套接字, ⽤于 UDP 协议) 

TCP慢但是稳定不会丢数据
UDP快但是可能会丢数据(黑客攻击)
确定了IP地址端口号(ipv4协议),TCP或UDP协议之后,计算机之间可以进行通信

UDP 和TCP

UDP简介

UDP --- User Data Protocol,用户数据报协议, 是⼀个⽆连接的简单的⾯向数据报的传输层协议。 UDP不提供可靠性, 它只是把应⽤程序传给IP层的数据报发送出去, 但是并不能保证它们能到达⽬的地。 由于UDP在传输数据报前不⽤在客户和服务器之间建⽴⼀个连接, 且没有超时重发等机制, 故⽽传输速度很快

UDP⼀般⽤于多点通信和实时的数据业务,

⽐如:语⾳⼴播、视频、QQ、TFTP(简单⽂件传送)

可以理解为写信

TCP简介

TCP(Transmission Control Protocol,传输控制协议)是面向连接的协议,也就是说,在收发数据前,必须和对方建立可靠的连接

一个TCP连接必须要经过三次“对话”才能建立起来,其中的过程非常复杂,只简单的描述下这三次对话的简单过程:
主机A向主机B发出连接请求数据包:“我想给你发数据,可以吗?”,这是第一次对话
主机B向主机A发送同意连接和要求同步(同步就是两台主机一个在发送,一个在接收,协调工作)的数据包:“可以,你什么时候发?”,这是第二次对话
主机A再发出一个数据包确认主机B的要求同步:“我现在就发,你接着吧!”,这是第三次对话
三次“对话”的目的是使数据包的发送和接收同步,经过三次“对话”之后,主机A才向主机B正式发送数据。

可以理解为打电话,先建立通道

TCP与UDP的区别:
1.基于连接与无连接

2.对系统资源的要求(TCP较多,UDP少)

3.UDP程序结构较简单

4.流模式与数据报模式

5.TCP保证数据正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证

UDP编程

网络调试助手工具下载
链接:https://pan.baidu.com/s/14qwiErUKlOfnCcvx9Edoeg
提取码:1122

发送数据

from socket import *
s = socket(AF_INET, SOCK_DGRAM) #创建套接字
addr = ('192.168.0.5', 8080) #准备接收方地址
data = input("请输入:")
s.sendto(data.encode(),addr)
#等待接收数据
redata = s.recvfrom(1024)
#1024表示本次接收的最大字节数
print(redata)
s.close()

接收数据

from socket import *
s = socket(AF_INET, SOCK_DGRAM) #创建套接字
addr = ('192.168.0.5', 8080) #准备接收方地址
data = input("请输入:")
s.sendto(data.encode(),addr)
#等待接收数据
redata = s.recvfrom(1024)
#1024表示本次接收的最大字节数
print(redata)
s.close()

绑定信息

让一个进程可以使用固定的端口,一般情况下,发送方不绑定端口,接收方会绑定

#绑定信息:让一个进程可以使用固定的端口
#一般情况下,发送方不绑定端口,接收方会绑定
from socket import *
s = socket(AF_INET, SOCK_DGRAM) #创建套接字
s.bind(('', 8788))   #绑定一个端口,ip地址和端⼝号,ip⼀般不⽤写
addr = ('192.168.0.5', 8080)   #准备接收方地址
data = input("请输入:")
s.sendto(data.encode(),addr)
redata = s.recvfrom(1024) #1024表示本次接收的最⼤字节数
print(redata)
s.close()

echo服务器

Echo服务是一种非常有用的用于调试和检测的工具。这个协议的作用也十分简单,接收到什么原封发回

from socket import *
#1创建套接字
udpSocket = socket(AF_INET, SOCK_DGRAM)
#2绑定本地信息,不使用随机分配的端口
bindAddr = ("",7088)
udpSocket.bind(bindAddr)#绑定
num = 0
while True:
    #接收对方发送的数据
    recvData = udpSocket.recvfrom(1024)
    print(recvData)
    #将接收到的数据回发给对方
    udpSocket.sendto(recvData[0],recvData[1])
    num += 1
    print("已将接收到的第%d个数据返回给对方,"%num)
udpSocket.close()

聊天室

from socket import *
import time
#1创建套接字
udpSocket = socket(AF_INET, SOCK_DGRAM)
bindAddr = ("",7088)
udpSocket.bind(bindAddr)#绑定
while True:
    #接收对方发送的数据
    recvData = udpSocket.recvfrom(1024)
    print('【%s】 %s.%s' %(time.ctime(),recvData[1],recvData[0].decode("GB2312")))
    a = input("请输入:")
    udpSocket.sendto(a.encode('GB2312'),('192.168.0.5',8080))
#5关闭套接字
udpSocket.close()

多线程实现全双⼯的聊天程序

'''
全双工(Full Duplex)是通讯传输的一个术语。通信允许数据在两个方向上同时传输(电话)
单工是只允许甲方向乙方传送信息,而乙方不能向甲方传送(收音机)
半双工:甲方发消息时乙方只能收不能发(对讲机)
'''
from socket import *
import time
import threading

udpSocket = socket(AF_INET, SOCK_DGRAM)  # 创建套接字
bindAddr = ('', 9090)
udpSocket.bind(bindAddr)  # 绑定端口
addIP = ('192.168.0.5', 8081)
def send():
    while True:
        str = input('请输入要发送的内容:')
        udpSocket.sendto(str.encode('gbk'), addIP)

def receive():
    while True:
        recvData = udpSocket.recvfrom(1024)
        print(recvData[0].decode('gbk'))

def main():
    t1 = threading.Thread(target = send)
    t2 = threading.Thread(target = receive)
    t1.start()
    t2.start()
if __name__=='__main__':
    main()

udp网络通信过程:(类似于发快递)
1,应用层编写数据(你好),然后向下层传递2,传输层在数据前面加上端口号(包括发送端口和目的端口)
3,网络层继续在前面加上IP地址(包括原IP和目的IP)
4,链路层再在前面加上mac地址(mac:硬件地址,用来定义网络设备的位置)
此时数据变成了:mac地址 IP地址 端口号 数据内容
之后通过网络传输给另一台计算机的链路层开始逐步解析判断

字符集

ASCII
#英文字符集 1个字节
ISO8859-1
#西欧字符集  1个字节
BIG5
#台湾的大五码,表示繁体汉字  2个字节
GB2312
#大陆使用最早、最广的简体中文字符集 2个字节
GBK
#GB2312的扩展,可以表示繁体中文  2个字节
GB18030
#最新GBK的扩展,可以表示汉字、维吾尔文、藏文等中华民族字符  2个字节
Unicode
#国际通用字符集  2个字节

推荐阅读