socket基础知识
1.简单的例程试水:单纯的实现了客户端连接服务器
#服务器
import socket
s = socket.socket()
#获取本机主机名
host = socket.gethostname()#本机ipv4地址
port = 2222 #端口号
s.bind((host, port))#绑定地址
s.listen(5)#TCP监听;数量是客户端的最大连接数
while True:
clientsocket, addr = s.accept()#被动接受TCP客户端连接,(阻塞式)等待连接的到来
print('Got connection from', addr)
msg='Thank you for connecting...'
clientsocket.send(msg.encode('utf-8'))
clientsocket.close()
#客户端
import socket
s = socket.socket()
host = socket.gethostname()
port = 2222
s.connect((host, port))#连接主机和端口
msg = s.recv(1024)
print(msg.decode('utf-8'))
2.客户端一直发送消息
#服务器
#服务器
import socket
s = socket.socket()
host = socket.gethostname()
port = 1234
s.bind((host, port))
s.listen(5)
clientsocket, addr = s.accept()
print('Got connection from', addr)
msg='Thank you for connecting...'
clientsocket.send(msg.encode('utf-8'))
while True:
data = clientsocket.recv(1024)
if data.decode('utf-8')=='exit':
print('connection closed')
break;
print('client send data is:',data.decode('utf-8'))
clientsocket.close()
#客户端
#客户端
import socket
s = socket.socket()
host = socket.gethostname()
port = 1234
s.connect((host, port))#连接主机和端口
msg = s.recv(1024)
print(msg.decode('utf-8'))
while True:
data = input('please input:')
s.send(data.encode())
if data=='exit':
print('connection closed')
break
运行结果:
3.客户端和服务器相互发送消息
#服务器
import socket
s = socket.socket()
host = socket.gethostname()
port = 1234
s.bind((host, port))
s.listen(5)
clientsocket, addr = s.accept()
print('Got connection from', addr)
msg='Thank you for connecting...'
clientsocket.send(msg.encode('utf-8'))
while True:
data = clientsocket.recv(1024).decode('utf-8')#服务器接收
if data=='exit':
print('connection closed')
break;
print('client send data is:',data)
msg = input("server input:")#服务器发送
if len(msg)==0:
continue
clientsocket.send(msg.encode('utf-8'))
clientsocket.close()
#客户端
import socket
s = socket.socket()
host = socket.gethostname()
port = 1234
s.connect((host, port))#连接主机和端口
msg = s.recv(1024)
print(msg.decode('utf-8'))
while True:
data = input('please input:')#客户端发送
s.send(data.encode())
if data=='exit':
print('connection closed')
break
msg = s.recv(1024).decode('utf-8')#客户端接收
if not msg:
continue
print('server send data is:',msg)
运行结果:
不过,与一个致命的问题,input这个会一直等待输入,只有你在控制台这里输入内容并回车后才可以显示TCP工具发送的数据,因为input这个方法是线程阻塞的,如果想实现实时收发,需要使用多线程,一个线程接收,一个线程发送;
4.客户端和服务器相互发信息:
开多线程:天哪:鬼知道为什么python shell会不行,找了一天毛病,还是会卡在input阻塞上:记住:一定在cmd中运行:一定在cmd中运行:一定在cmd中运行!!!!
#服务器
import socket
from time import sleep
import threading
s = socket.socket()
host = socket.gethostname()
port = 1234
s.bind((host, port))
s.listen(5)
clientsocket, addr = s.accept()
print('Got connection from', addr)
msg='Thank you for connecting...'
clientsocket.send(msg.encode('utf-8'))
def recvData():
while True:
data = clientsocket.recv(1024).decode('utf-8')#服务器接收
if data=='exit':
print('connection closed')
break;
print('client send data is:',data)
s.close()
if __name__ == '__main__':
t1 = threading.Thread(target=recvData)
t1.start()
while True:
msg = input("")#服务器发送
if len(msg)==0:
continue
clientsocket.send(msg.encode('utf-8'))
if msg=='exit':
break;
clientsocket.close()
#客户端
import socket
from time import sleep
import threading
s = socket.socket()
host = socket.gethostname()
port = 1234
s.connect((host, port))#连接主机和端口
msg = s.recv(1024)
print(msg.decode('utf-8'))
def recvData():
while True:
msg = s.recv(1024).decode('utf-8')#客户端接收
if not msg:
continue
print('server send data is:',msg)
if __name__ == '__main__':
t1 = threading.Thread(target=recvData)
t1.start()
while True:
data = input('')#客户端发送
s.send(data.encode())
if data=='exit':
print('connection closed')
break
s.close()
运行结果:
5.服务器作为中介:两个客户相互发消息
import socket
import threading
users = {}#用户字典,也可以链接数据库
def run(ck,ca):
userName = ck.recv(1024).decode('utf-8')#用户发送的信息
users[userName] = ck #解码并存储用户的信息
print(userName,'已链接到服务器')
while True:
data = ck.recv(1024).decode('utf-8')
s = data.split(':')#分割字符串得到发送的用户名和客户端发送的信息
users[s[0]].send((userName+'说:'+s[1]).encode('utf-8'))#要发送信息的客户端,向目标客户端发送信息
def start():
server = socket.socket()
ipStr = socket.gethostname()
portStr = 9846
server.bind((ipStr, portStr))
#2:bind()的参数是一个元组的形式
server.listen(10)#设置监听,和设置连接的最大的数量
print("服务器启动成功")
while True:
ck, ca = server.accept()#接受所连接的客户端的信息
# 其中ca是ip和端口号组成的元组,ck有关客户端的信息
t = threading.Thread(target=run, args=(ck, ca))#每连接一个客户端就开启一个线程
#其中Thread函数中的传入函数的参数也是以元组的形式
t.start()#开启线程
s = threading.Thread(target=start)#启用一个线程开启服务器
s.start()#开启线程
import socket
import threading
ck=None
def getInfo():
while True:
data = ck.recv(1024).decode('utf-8')#用于接受服务其发送的信息
print(data)
#客户1
def connectServer():
global ck
client = socket.socket()
ipStr = socket.gethostname()
portStr = 9846
username = 'client1'
client.connect((ipStr,portStr))
client.send(username.encode('utf-8'))
ck = client
t=threading.Thread(target = getInfo)
t.start()
def sendMail(msg):
sendStr = 'client2' + ":" + msg
ck.send(sendStr.encode("utf-8"))
if __name__ == "__main__":
connectServer();
while True:
msg = input('')
sendMail(msg);
#客户2
import socket
import threading
ck=None
def getInfo():
while True:
data = ck.recv(1024).decode('utf-8')#用于接受服务其发送的信息
print(data)
def connectServer():
global ck
client = socket.socket()
ipStr = socket.gethostname()
portStr = 9846
username = 'client2'
client.connect((ipStr,portStr))
client.send(username.encode('utf-8'))
ck = client
t=threading.Thread(target = getInfo)
t.start()
def sendMail(msg):
sendStr = 'client1' + ":" + msg
ck.send(sendStr.encode("utf-8"))
if __name__ == "__main__":
connectServer();
while True:
msg = input('')
sendMail(msg);
运行结果: