目标是写一个python的p2p聊天的项目,这里先说一下python socket的基础课程

一、Python Socket 基础课程

Socket就是套接字,作为BSD UNIX的进程通信机制,取后一种意思。通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。在Internet上的主机一 般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。Socket正如其英文原 意那样,像一个多孔插座。一台主机犹如布满各种插座的房间,每个插座有一个编号,有的插座提供220伏交流电, 有的提供110伏交流电,有的则提供有线电视节目。 客户软件将插头插到不同编号的插座,就可以得到不同的服务

Socket连接的步骤

(1)服务器监听:是服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态。

(2)客户端请求:是指由客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。

(3)连接确认:是指当服务器端套接字监听到或者说接收到客户端套接字的连接请求,它就响应客户端套接字的请求,建立一个新的线程,把服务器端套接 字的描述发给客户端,一旦客户端确认了此描述,连接就建立好了。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。

二、服务端程序

因为很喜欢看三体,所以这个服务端就起名叫红岸,红岸基地的主要作用就是作为server端来使用,转发双方的通信,现在是调试阶段,先使用socket写单线程的,以后会使用socketserver或者多线程来重新写一个

先建立一个连接列表

#-*- coding: utf-8 -*-

importselectimportsocket

inBufSize= 4096outBufSize= 4096CONNECTION_LIST= []

构造函数

def __init__(self,port=5247):#todo 使用socketserver来写

self.serverSocket =socket.socket(socket.AF_INET, socket.SOCK_STREAM)

self.serverSocket.bind(('', port))

self.serverSocket.listen(5)print "server wait for connect...."self.socketsMap= {} #socket session字典 id : socket

self.idMap = {} #socket session 字典 socket:id

CONNECTION_LIST.append(self.serverSocket)

socketsMap和idMap是分别建立这id和socket之间的对应字典,P2P聊天的时候通过socket来找发送者id和通过接受者id来找socket

主要的处理函数是这样的

defsocet_handle(self):while 1:#Get the list sockets which are ready to be read through select

read_sockets, write_sockets, error_sockets =select.select(CONNECTION_LIST, [], [])for sock inread_sockets:#New connection

if sock == self.serverSocket:#用户通过主socket(即服务器开始创建的 socket,一直处于监听状态)来登录

#Handle the case in which there is a new connection recieved through server_socket

sockfd, addr =self.serverSocket.accept()

id= sockfd.recv(100)

self.login(id,sockfd)else:

self.chat(sock)

通过select来监听所有的连接,select是一个非阻塞的监听程序,监听文件的读,写,错误,函数用法是select.select(readable_iterable,writeble_iterable,error_iterable,timeout).

如果用户是使用主socket(一直在监听的端口,用户登录时要连接到这个端口,然后再在别的端口通信),就要登录函数

登录函数如下

def login(self,id,sock):#新用户登录

print "%s login"%id

self.socketsMap[id]=sock

self.idMap[sock]=id

sock.send('hello %s,you login successed'%id)

CONNECTION_LIST.append(sock)#要在这里把socket加进来才行

在CONNECTION_LIST中把会话加进去,然后返回一个问候信息

聊天和广播程序

def chat(self,sock):#点对点聊天,发送消息格式id||信息

try:

data=sock.recv(inBufSize)exceptException:

sock.send("remote is offline")

sock.close()else:

remote_id= data.split('||')[0]

message= data.split('||')[1]print "id = %s,message = %s"%(remote_id,message)

local_id=self.idMap[sock]if remote_id == 'all':

self.broadcast(local_id,message)else:

self.p2psend(local_id,message,remote_id)defp2psend(self,local_id,message,remote_id):

remote_socket=self.socketsMap[remote_id]

message_send= "%s said : %s" %(local_id, message)try:

remote_socket.sendall(message_send)exceptException,e:printe

remote_socket.close()

CONNECTION_LIST.remove(remote_socket)defbroadcast(self,local_id,message):for sock inCONNECTION_LIST:if sock ==self.serverSocket:continue

else:try:

message_send= "%s said : %s" %(local_id, message)

sock.send(message_send)exceptException,e:printe

sock.close()

CONNECTION_LIST.remove(sock)continue

服务端的完全体如下

#-*- coding: utf-8 -*-

importselectimportsocket

inBufSize= 4096outBufSize= 4096CONNECTION_LIST=[]classChatServer:def __init__(self,port=5247):#todo 使用socketserver来写

self.serverSocket =socket.socket(socket.AF_INET, socket.SOCK_STREAM)

self.serverSocket.bind(('', port))

self.serverSocket.listen(5)print "server wait for connect...."self.socketsMap= {} #socket session字典 id : socket

self.idMap = {} #socket session 字典 socket:id

CONNECTION_LIST.append(self.serverSocket)def login(self,id,sock):#新用户登录

print "%s login"%id

self.socketsMap[id]=sock

self.idMap[sock]=id

sock.send('hello %s,you login successed'%id)

CONNECTION_LIST.append(sock)#要在这里把socket加进来才行

def chat(self,sock):#点对点聊天,发送消息格式id||信息

try:

data=sock.recv(inBufSize)exceptException:

sock.send("remote is offline")

sock.close()else:

remote_id= data.split('||')[0]

message= data.split('||')[1]print "id = %s,message = %s"%(remote_id,message)

local_id=self.idMap[sock]if remote_id == 'all':

self.broadcast(local_id,message)else:

self.p2psend(local_id,message,remote_id)defp2psend(self,local_id,message,remote_id):

remote_socket=self.socketsMap[remote_id]

message_send= "%s said : %s" %(local_id, message)try:

remote_socket.sendall(message_send)exceptException,e:printe

remote_socket.close()

CONNECTION_LIST.remove(remote_socket)defbroadcast(self,local_id,message):for sock inCONNECTION_LIST:if sock ==self.serverSocket:continue

else:try:

message_send= "%s said : %s" %(local_id, message)

sock.send(message_send)exceptException,e:printe

sock.close()

CONNECTION_LIST.remove(sock)continue

defsocet_handle(self):while 1:#Get the list sockets which are ready to be read through select

read_sockets, write_sockets, error_sockets =select.select(CONNECTION_LIST, [], [])for sock inread_sockets:#New connection

if sock == self.serverSocket:#用户通过主socket(即服务器开始创建的 socket,一直处于监听状态)来登录

#Handle the case in which there is a new connection recieved through server_socket

sockfd, addr =self.serverSocket.accept()

id= sockfd.recv(100)

self.login(id,sockfd)else:

self.chat(sock)defmain(self):

self.socet_handle()

self.serverSocket.close()if __name__ == '__main__':

chat_server_obj=ChatServer()

chat_server_obj.main()

三、客户端程序

客户端程序的名字是叶文洁和监听员1379,不要回答!不要回答!不要回答!

主要就是使用select来监听sys.stdin和socket,来活儿了就要及时处理

defsocket_handler(self):while 1:

rlist= [sys.stdin, self.client_socket] #接收列表

read_list, write_list, error_list = select.select(rlist, [], [], 2)for sock inread_list:#incoming message from remote server

if sock ==self.client_socket:

data= sock.recv(4096)if notdata:print '\nDisconnected from chat server'sys.exit()else:#print data

sys.stdout.write(data)

self.prompt()#user entered a message

else:

msg=sys.stdin.readline()

remote_id= raw_input("Please input remote id:")

msg_send= "%s||%s"%(remote_id,msg)

self.client_socket.send(msg_send)

self.prompt()

快吃中午饭了,就不详细说了,也没什么好详细说的,很简单,客户端完全体如下,叶文洁的id是1,监听员1379的id是2,后边可以改成手动指定的,在群聊里面加上托马斯维德和程心

#-*- coding:utf-8 -*-

importsocket, select, string, sys

HOST= '127.0.0.1'PORT= 5247ID= '1'

classChatClient:def __init__(self):

self.client_socket=socket.socket(socket.AF_INET, socket.SOCK_STREAM)

self.client_socket.settimeout(2)

self.connect()defconnect(self):try:

self.client_socket.connect((HOST, PORT))

self.client_socket.send(ID)exceptException,e:print 'Unable to connect because of %s'%e

sys.exit()else:print 'Connected to remote host. Start sending messages'self.prompt()defprompt(self):

sys.stdout.write('\n')

sys.stdout.flush()defsocket_handler(self):while 1:

rlist= [sys.stdin, self.client_socket] #接收列表

read_list, write_list, error_list = select.select(rlist, [], [], 2)for sock inread_list:#incoming message from remote server

if sock ==self.client_socket:

data= sock.recv(4096)if notdata:print '\nDisconnected from chat server'sys.exit()else:#print data

sys.stdout.write(data)

self.prompt()#user entered a message

else:

msg=sys.stdin.readline()

remote_id= raw_input("Please input remote id:")

msg_send= "%s||%s"%(remote_id,msg)

self.client_socket.send(msg_send)

self.prompt()if __name__ == '__main__':

chat_client_obj=ChatClient()

chat_client_obj.socket_handler()

githu地址

https://github.com/wuxie2015/tri_body_chat

聊天效果如下

python实现简易聊天需要登录_python socket编程 实现简单p2p聊天程序相关推荐

  1. python socket编程 实现简单p2p聊天程序

    转载自:https://www.cnblogs.com/wuxie1989/p/7204887.html python socket编程 实现简单p2p聊天程序 目标是写一个python的p2p聊天的 ...

  2. python webdriver 等待网页已登录_python基础编程:python+selenium实现163邮箱自动登陆的方法...

    本文介绍了 让我们先来预览一下代码运行效果吧: 首先分析163邮箱登陆页面的网页结构(按F12或单击鼠标右键选择审查元素) 1.定位到登陆框(注意登录框是一个iframe,如果不定位到iframe的话 ...

  3. Java网络编程以及简单的聊天程序

    网络编程技术是互联网技术中的主流编程技术之一,懂的一些基本的操作是非常必要的.这章主要讲解网络编程,UDP和Socket编程,以及使用Socket做一个简单的聊天软件. 全部代码下载:链接 1.网络编 ...

  4. java socket通信 客户端_JavaのSocket编程之简单客户端与服务器端通信

    Socket编程之简单客户端与服务器端通信 socket 通常用来实现客户端和服务端的连接,socket 是Tcp/Ip协议的一个十分流行的编程界面,一个socket 由一个Ip地址和一个端口号唯一确 ...

  5. Socket编程之简单介绍 - 蓝天下的雨 - 博客园

    Socket编程之简单介绍 - 蓝天下的雨 - 博客园 Socket编程之简单介绍 - 蓝天下的雨 - 博客园 Socket编程之简单介绍 2013-03-19 15:27 by 蓝天下的雨, 878 ...

  6. python socket多线程 获取朋友列表_python socket多线程通讯实例分析(聊天室)

    本文实例讲述了python socket多线程通讯方法.分享给大家供大家参考,具体如下: #!/usr/bin/evn python """ 这是一个Socket+多进程 ...

  7. 用python画分时图_Python socket编程之四:模拟分时图

    建立 socket,先运行服务器,再运行客户端,建立连接后服务器从本地数据库调数据一截一截地发送给客户端,客户端接受数据绘图模拟分时图 1.socket # -*- coding: utf-8 -*- ...

  8. python的socket编程_Python Socket编程详细介绍

    在使用Python做socket编程时,由于需要使用阻塞(默认)的方式来读取数据流,此时对于数据的结束每次都需要自己处理,太麻烦.并且网上也没找到太好的封装,所以就自己写了个简单的封装. 封装思路 1 ...

  9. python send 案例_python socket编程入门(编写server实例)+send 与sendall的区别与使用方法...

    python 编写server的步骤: 1. 第一步是创建socket对象.调用socket构造函数.如: socket = socket.socket( family, type ) family参 ...

最新文章

  1. Python炫技操作:条件语句的七种写法
  2. JAVA静态方法是否可以被继承 6,JAVA静态方法是否可以被继承?
  3. 对Java单例模式 volatile关键字作用的理解
  4. 项目整体管理:项目整体管理实现过程
  5. Vue使用jsPdf将页面导出成pdf文件
  6. 阿里资深技术工程师: 程序员怎样快速成长?
  7. React开发(102):别写立即执行函数
  8. 【可临摹UI设计干货】APP UI界面的版式设计理论!
  9. 怎么看曲线有没有斜渐近线_?成考结束后,怎么看你有没有被录取?
  10. WINCE的KITL调试环境
  11. SSM-水果商城-导入项目-学习-2
  12. 单片机双击 长按 c语言,51单片机按键检测源程序(实现单击、双击、长按等功能)...
  13. 经济学论文素材之汇率波动的外汇风险
  14. Bad Request This combination of host and port requires TLS. postman
  15. 40页PPT详解:京东大数据基础构架与创新应用
  16. 等差数列java用等差公式写_等差数列
  17. 基于OpenCV的图像透视变换详解(从理论到实现再到实践)
  18. Eclipse报错DataIntegrityViolationException异常解决办法
  19. 使用PIL包给图片增加水印
  20. 动态规划:由背包问题入门1

热门文章

  1. OPengl实现小球围绕大球旋转的效果
  2. 时间序列分析中统计模型statsmodels.tsa.arima_model
  3. 《富豪谷底求生》纪录片记录
  4. 西南科技大学数据库实验二(Oracle 11g)
  5. androidQ(10.0) 读取蓝牙设备当前电量并显示
  6. 什么是JMS(消息服务)
  7. SQLyog的免费使用方式
  8. MySql安装成功后没有my.ini文件怎么办?
  9. openCV专栏(八):图像轮廓:绘制轮廓
  10. 两级分销加两级代理佣金计算工具