zoukankan      html  css  js  c++  java
  • 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() 
    
    
  • 相关阅读:
    Ubuntu下MySQL
    submit踩的坑
    转发,重定向以及区别和简单的session对象(转)
    Markdown链接打开新页面而非本页面跳转,补:target属性
    登录失败使用session传数据
    git安装连接码云提交
    Markdown的超链接由新窗口打开
    GitHub搜索相关项目
    mysql安装
    jdk的安装和配置
  • 原文地址:https://www.cnblogs.com/zzsy/p/12236128.html
Copyright © 2011-2022 走看看