- from socket import *
- serverSocket=socket(AF_INET,SOCK_STREAM)
- serverSocket.bind(("",8899))
- serverSocket.listen(5)
- newSocket,clientAddr=serverSocket.accept() #返回新的套接字和对方的 ip 地址和端口号
- print("有客户端连接")
- recvDate=newSocket.revc(1024)
- print("%s%s"%(str(clientAddr),recvDate))
- newSocket.send("thank you !")
- newSocket.close()
- serverSocket.close()
- from socket import *
- # 创建 socket
- tcpSerSocket = socket(AF_INET, SOCK_STREAM)
- # 绑定本地信息
- address = ('', 8899)
- tcpSerSocket.bind(address)
- # 使用 socket 创建的套接字默认的属性是主动的, 使用 listen 将其变为被动的, 这样就可以接收别人的链接了
- tcpSerSocket.listen(5)
- # 如果有新的客户端来链接服务器, 那么就产生一个新的套接字专门为这个客户端服务器
- # newSocket 用来为这个客户端服务
- # tcpSerSocket 就可以省下来专门等待其他新客户端的链接
- newSocket, clientAddr = tcpSerSocket.accept()
- # 接收对方发送过来的数据, 最大接收 1024 个字节
- recvData = newSocket.recv(1024)
- print('接收到的数据为:%d',recvData.decode("gb2312"))
- # 发送一些数据到客户端
- newSocket.send("thank you !".encode("gb2312"))
- # 关闭为这个客户端服务的套接字, 只要关闭了, 就意味着为不能再为这个客户端服务了, 如果还需要服务, 只能再次重新连接
- newSocket.close()
- # 关闭监听套接字, 只要这个套接字关闭了, 就意味着整个程序不能再接收任何新的客户端的连接
- tcpSerSocket.close()
- # 多线程服务器, 接收客户机链接
- from socket import *
- from threading import *
- def recv_send_Thread(customer_sock,addr):
- while True:
- str=customer_sock.recv(1024) # 循环接收客户端发来的信息
- customer_sock.send(str)
- print(str.decode("gb2312"))
- if str.decode("gb2312") == 'exit':
- print("关闭套接字")
- customer_sock.close()
- break
- customer_sock.close()
- # 创建服务器的 socket
- server_tcp_socket=socket(AF_INET,SOCK_STREAM)
- # 解决 MSL 问题, 如果服务器先断开链接, 则第四次会后不必等 2 被时间, 即可链接, 避免出现等到 2 倍时间内地址被占用的问题
- server_tcp_socket.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
- #bind 绑定地址和端口
- server_tcp_socket.bind(("",8899))
- # 设置监听 listen
- server_tcp_socket.listen(5)
- while True:
- new_socket,new_addr=server_tcp_socket.accept() #等待接受客户端链接
- print(("与客户 %s 建立链接成功, 可以交流" % new_addr[0]))
- new_socket.send(("您好客户 %s, 已经建立链接, 可以交流" % new_addr[0]).encode("gb2312")) # 链接成功后, 发送链接信息
- th=Thread(target=recv_send_Thread,args=(new_socket,new_addr))
- th.start()
- th.join()
- # 收发信息
- # 释放链接
- server_tcp_socket.close()
- #select 版本的服务器代码
- # 轮询的方式检测, 效率低; 32 位最多链接 1023 个, 64 位最多链接 2045 个端口
- from socket import *
- from select import select
- from sys import *
- def main():
- server = socket(AF_INET,SOCK_STREAM)
- # 解决 MSL 问题, 如果服务器先断开链接, 则第四次会后不必等 2 被时间, 即可链接, 避免出现等到 2 倍时间内地址被占用的问题
- server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
- address = ("",8000)
- server.bind(address)
- server.listen(1024)
- inputs=[server,stdin]
- running = True
- while True:
- readable,writeable,exceptional = select(inputs,[],[])
- for sock in readable:
- if(sock == server):
- s,addr = server.accept()
- print(s)
- inputs.append(s)
- s.send("已经建立好链接".encode("gb2312"))
- elif sock == stdin:
- cmd = stdin.readline()
- running = False
- break
- else:
- msg = sock.recv(1024)
- print(msg.decode("gb2312"))
- sock.send(("服务器收到了客户端发送的:%s"%(msg.decode("gb2312"))).encode("gb2312"))
- if msg.decode("gb2312")=='exit':
- #sock.send("将要断开链接".encode("gb2312"))
- sock.close()
- inputs.remove(sock)
- if running==False:
- break
- server.close()
- print("服务器关闭")
- if __name__ =="__main__":
- main()
- # epool 方式实现服务器
- # epool 是没有套接字上限, 是时间通知机制. pool 是轮询机制, 解决了套接字有上限的问题.
- from socket import *
- from select import *
- s = socket(AF_INET,SOCK_STREAM)
- # 解决 MSL 问题, 如果服务器先断开链接, 则第四次会后不必等 2 被时间, 即可链接, 避免出现等到 2 倍时间内地址被占用的问题
- s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
- addr=("",8000)
- s.bind(addr)
- s.listen(10)
- epoll_l = epoll()
- epoll_l.register(s.fileno(),EPOLLIN|EPOLLET)
- connections={}
- addresses={}
- while True:
- epoll_list = epoll_l.poll()
- for fd,events in epoll_list:
- if fd == s.fileno():
- soc,addres = s.accept()
- soc.send("已经链接链接".encode("gb2312"))
- connections[soc.fileno()] = soc
- addresses[soc.fileno()] = addres
- epoll_l.register(soc.fileno(), EPOLLIN|EPOLLET)
- elif events == EPOLLIN:
- msg = connections[fd].recv(1024)
- print(msg.decode("gb2312"))
- connections[fd].send(("收到了客户端的 %s"%msg.decode("gb2312")).encode("gb2312"))
- if msg.decode("gb2312") == "exit":
- epoll_l.unregister(fd)
- connections[fd].close()
- print()
- else:
- pass
- # 协程, 生成器版本
- import time
- def A():
- while True:
- print("----a----")
- yield
- time.sleep(1)
- def B(c):
- while True:
- print("----b----")
- c.__next__()
- time.sleep(1)
- a=A()
- print(a.__next__())
- b=B(a)
- # 协程, greenlet 版本
- from greenlet import greenlet
- import time
- def test1():
- while True:
- print("A")
- gr2.switch()
- time.sleep(1)
- def test2():
- while True:
- print("B")
- gr1.switch()
- time.sleep(1)
- gr1=greenlet(test1)
- gr2=greenlet(test2)
- gr1.switch()
- # gevent 版本的服务器
- import gevent
- #from socket import *
- from gevent import socket,monkey
- monkey.patch_all()
- def handle_request(conn):
- while True:
- data=conn.recv(1024)
- if not data:
- conn.close()
- break
- print("recv:%s"%data.decode("gb2312"))
- conn.send(data)
- def server(port):
- s=socket.socket()
- # 解决 MSL 问题, 如果服务器先断开链接, 则第四次会后不必等 2 被时间, 即可链接, 避免出现等到 2 倍时间内地址被占用的问题
- #s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
- s.bind(("",port))
- s.listen(5)
- while True:
- cli,addr = s.accept()
- cli.send("已经连接成功".encode("gb2312"))
- gevent.spawn(handle_request,cli)
- if __name__=="__main__":
- server(8000)
客户端程序:
- # 客户端程序
- from socket import *
- # 创建 socket
- tcpClientSocket = socket(AF_INET, SOCK_STREAM)
- # 链接服务器
- serAddr = ('192.168.249.210', 8000)
- tcpClientSocket.connect(serAddr) # 建立连接
- recvData = tcpClientSocket.recv(1024) # 接收数据
- print('接收到的数据为:'+recvData.decode("gb2312"))
- while True:
- # 提示用户输入数据
- sendData = input("请输入要发送的数据:")
- tcpClientSocket.send(sendData.encode("gb2312")) # 循环发送数据
- if sendData == "exit":
- break
- # 接收对方发送过来的数据, 最大接收 1024 个字节
- recvData = tcpClientSocket.recv(1024) # 循环接收数据
- print('接收到的数据为:'+recvData.decode("gb2312"))
- # 关闭套接字
- tcpClientSocket.close()
来源: http://www.bubuko.com/infodetail-2987843.html