Socket网络编程

Socket网络编程

  • Socket:通过网络完成进程间通信的方式
  • Socket的英文原义是“插孔”。通常也称作"套接字“

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

Socket编程-udp

  • UDP --- User Data Protocol用户数据报协议, 是⼀个⽆连接的简单的⾯向数据报的传输层协议。 UDP不提供可靠性, 它只是把应⽤程序传给IP层的数据报发送出去, 但是并不能保证它们能到达⽬的地。 由于UDP在传输数据报前不⽤在客户和服务器之间建⽴⼀个连接, 且没有超时重发等机制, 故⽽传输速度很快,UDP⼀般⽤于多点通信和实时的数据业务, ⽐如:语⾳,⼴播,视频, QQ,TFTP(简单⽂件传送)

udp套接字服务端与客户端实例

服务器端
import socket
server=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
server.bind(('127.0.0.1',8080))
while True:
    msg,client_addr=server.recvfrom(1024)         #(接收客户端消息和客户端ip和端口)如果接收的数据量小于发送的数据量就会出现丢包的问题
    server.sendto(msg.upper(),client_addr)        #发送数据内容和客户端ip和端口
server.close()


客户端
import socket
client=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
ip_port=('127.0.0.1',8080)
while True:
    msg=input('>>>').strip()                     #udp是数据报协议,自带报头,每发一次数据对应一条收,udp是无连接的即使收空能发送,因为发空也会有一个报头
    client.sendto(msg.encode('utf-8'),ip_port)   #每次发送数据量最好不要超过512个字节,无连接意味着发送要指定对方的ip和port
    data,server_addr=client.recvfrom(1024)       #接收会拿到接收对方发送的数据和对方的ip和port,是一个元组的形式,所以解包即可
    print(data)
client.close()

Socket编程-tcp

TCP(Transmission Control Protocol,传输控制协议是面向连接的协议,也就是说,在收发数据前,必须和对方建立可靠的连接,一个TCP连接必须要经过三次“对话”才能建立起来,其中的过程非常复杂,–可以理解为打电话,先建立通道.

tcp是基于连接的,必须先启动服务端,然后在启动客户端连接服务端

tcp服务端

ss = socket() #创建服务器套接字
ss.bind()      #把地址绑定到套接字
ss.listen()      #监听链接
inf_loop:      #服务器无限循环
    cs = ss.accept() #接受客户端链接
    comm_loop:         #通讯循环
        cs.recv()/cs.send() #对话(接收与发送)
    cs.close()    #关闭客户端套接字
ss.close()        #关闭服务器套接字(可选)

tcp客户端

 cs = socket()    # 创建客户套接字
 cs.connect()    # 尝试连接服务器
comm_loop:        # 通讯循环
     cs.send()/cs.recv()    # 对话(发送/接收)
 cs.close()            # 关闭客户套接字
完整版TCP服务端
服务端
from socket import *
tcpSerSocket = socket(AF_INET, SOCK_STREAM)
address = (‘’, 7788) 
tcpSerSocket.bind(address)
tcpSerSocket.listen(5)#设置最大连接数
newSocket, clientAddr = tcpSerSocket.accept()
# 如果有新的客户端来链接服务器, 那么就产⽣⼀个新的套接字# newSocket⽤来为这个客户端服务(10086小妹)
# tcpSerSocket就可以省下来等待其他新客户端的链接 
# 接收对⽅发送过来的数据, 最⼤接收1024个字节
recvData = newSocket.recv(1024)  #接收tcp数据
# 发送⼀些数据到客户端
newSocket.send(“thank you !”)   #发送tcp数据
# 关闭为这个客户端服务的套接字, 只要关闭了, 就意味着为不能再为这个客户端服务了
newSocket.close() 
# 关闭监听套接字, 只要这个套接字关闭了, 就意味着整个程序不能再接收任何新的客户端的连接
tcpSerSocket.close() 



from socket import *
clientSocket = socket(AF_INET, SOCK_STREAM)

serAddr = ('192.168.1.17', 7788)
#链接服务器
clientSocket.connect(serAddr)
clientSocket.send(b"hello")
recvData = clientSocket.recv(1024)
print("接收到的数据为:", recvData)
clientSocket.close()

多进程服务器

from socket import *
from multiprocessing import *
from time import sleep# 处理客户端的请求并为其服务
def dealWithClient(newSocket,destAddr):
	while True:         
		recvData = newSocket.recv(1024)
    	if len(recvData)>0:
    		print('recv[%s]:%s'%(str(destAddr), recvData))   
    	else:            
    		print('[%s]客户端已经关闭'%str(destAddr))  
    		break
         newSocket.close()
def main():
	serSocket = socket(AF_INET, SOCK_STREAM)
	serSocket.setsockopt(SOL_SOCKET, SO_REUSEADDR , 1)
 	localAddr = ('', 7788) 
 	serSocket.bind(localAddr)
 	serSocket.listen(5)
 	try:
 		while True:      
        	print('-----主进程, , 等待新客户端的到来------’)      
            newSocket,destAddr = serSocket.accept()
       	 	print(‘-----主进程, , 接下来创建⼀个新的进程负责数据处理’)   
        	client = Process(target=dealWithClient, args=(newSocket,destAddr))        				client.start()   
        	#因为已经向⼦进程中copy了⼀份(引⽤) , ⽗进程中这个套接字也没有用处了     
        	#所以关闭       
        	newSocket.close()
   finally:     
        #当为所有的客户端服务完之后再进⾏关闭,
	 表示不再接收新的客户端的链接   
     serSocket.close()
if __name__ == '__main__’:  
	main() 

多线程服务器

from socket import *
from threading import Thread
from time import sleep
# 处理客户端的请求并执⾏事情
def dealWithClient(newSocket,destAddr):
	while True:
		recvData = newSocket.recv(1024)
		if len(recvData)>0:
			print('recv[%s]:%s'%(str(destAddr), recvData))
		else:
			print('[%s]客户端已经关闭'%str(destAddr))
			break
			newSocket.close()
def main():
	serSocket = socket(AF_INET, SOCK_STREAM)
	serSocket.setsockopt(SOL_SOCKET, SO_REUSEADDR , 1)
	localAddr = ('', 7788)
	serSocket.bind(localAddr)
	serSocket.listen(5)
try:
	while True:
		print(‘-----主进程, , 等待新客户端的到来------’)
		newSocket,destAddr = serSocket.accept()
		print(‘主进程接下来创建⼀个新的线程负责处理 ‘, str(destAddr)))
        client = Thread(target=dealWithClient, args=(newSocket,destAddr))
        client.start()
        #因为线程中共享这个套接字, 如果关闭了会导致这个套接字不可⽤,
        #但是此时在线程中这个套接字可能还在收数据, 因此不能关闭
        #newSocket.close()
finally:
     serSocket.close()
if __name__ == '__main__’:
     main() 

posted @ 2020-01-27 15:23  zz洲神在此  阅读(194)  评论(0编辑  收藏  举报