以您熟悉的编程语言为例完成一个hello/hi的简单的网络聊天程序

在这片博文我们将使用python完成一个hello/hi的简单的网络聊天程序

先做一下准备工作

1.linux的socket基础api:

使用socket()创建套接字

int socket(int af, int type, int protocol);

af为IP地址类型,AF_INE和AF_INET6分别对应ipv4和ipv6地址type是数据传输方式,Sock_stream(面向连接套接字)和sock_dgram(无连接套接字)protocol是传输协议,IPPROTO_TCP和IPPROTO_UDP

使用bind()将套接字与特定的ip地址和端口号绑定
int bind(int sock, struct sockaddr *addr, socklen_t addrlen); 
sock 为 socket 文件描述符,addr 为 sockaddr 结构体变量的指针,addrlen 为 addr 变量的大小

客户端使用connect()建立连接
int connect(int sock, struct sockaddr *serv_addr, socklen_t addrlen);  
使用listen()函数让套接字进入被动监听状态int listen(int sock, int backlog)sock 为需要进入监听状态的套接字,backlog 为请求队列的最大长度。

使用 write() 可以向套接字中写入数据
ssize_t write(int fd, const void *buf, size_t nbytes)fd 为要写入的文件的描述符,buf 为要写入的数据的缓冲区地址,nbytes 为要写入的数据的字节数
使用 read() 可以从套接字中读取数据
ssize_t read(int fd, void *buf, size_t nbytes);
fd 为要读取的文件的描述符,buf 为要接收数据的缓冲区地址,nbytes 为要读取的数据的字节数

2.python中相关的库

2.1socket库:这是python提供的基本的 低级别的网络服务,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口的全部方法

  我们用 socket()函数来创建套接字,语法格式如下:

  socket.socket([family[, type[, proto]]])

  通过调用底层socket接口,提供有一下方法:

s.bind() 绑定地址(host,port)到套接字, 在AF_INET下,以元组(host,port)的形式表示地址。
s.listen() 开始TCP监听。backlog指定在拒绝连接之前,操作系统可以挂起的最大连接数量。该值至少为1,大部分应用程序设为5就可以了。
s.accept() 被动接受TCP客户端连接,(阻塞式)等待连接的到来
客户端套接字
s.connect() 主动初始化TCP服务器连接,。一般address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。
s.connect_ex() connect()函数的扩展版本,出错时返回出错码,而不是抛出异常
公共用途的套接字函数
s.recv() 接收TCP数据,数据以字符串形式返回,bufsize指定要接收的最大数据量。flag提供有关消息的其他信息,通常可以忽略。
s.send() 发送TCP数据,将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。

2.2 threading库:

  接受和发送消息的方法都是阻塞的,客户端和服务端之间要进行正常聊天,需要一个线程来接受对方的消息,另一个线程来发送消息,

  通过python的threading库来实现这个功能,示例如下:

  t=threading.Thread(target=tcp_recv, args=(s, addr))

  t.start()

3. 实现hello/hi的简单的网络聊天程序的python代码

客户端:

import socket

import threading

import time

from time import strftime, localtime

#定义套接字

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 建立连接:

addr=(‘127.0.0.1‘, 9999)

s.connect(addr)

def tcp_recv(s,addr):

while True:

print(strftime("%Y-%m-%d %H:%M:%S", localtime()),s.recv(1024).decode(‘utf-8‘))

t=threading.Thread(target=tcp_recv, args=(s, addr))

t.start()

while True:

msg=input()

# 发送数据:

s.send((‘ From client : %s‘% msg).encode(‘utf-8‘))

if msg ==‘exit‘:

break

s.send(b‘exit‘)

s.close()

服务端:

import threading

import socket

from time import strftime, localtime

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

s.bind((‘127.0.0.1‘, 9999))

s.listen(5)

print(‘Waiting for connection...‘)

def tcp_recv(sock, addr):

while True:

data = sock.recv(1024)

if not data or data.decode(‘utf-8‘) == ‘exit‘:

break

print(strftime("%Y-%m-%d %H:%M:%S", localtime()),data.decode(‘utf-8‘))

#sock.send((‘Server:%s‘% input()).encode(‘utf-8‘))

sock.close()

print(‘Connection from %s:%s closed.‘ % addr)

def tcp_send(sock):

while True:

msg = input()

if msg == ‘exit‘:

exit

#print(‘Client:%s‘%data.decode(‘utf-8‘))

sock.send((‘ From server : %s‘% msg).encode(‘utf-8‘))

print(‘Connection from %s:%s closed.‘ % addr)

sock, addr = s.accept()

print(‘Accept new connection from %s:%s...‘ % addr)

sock.send(b‘ From server : Welcome!‘)

while True:

# 接受一个新连接:

# 创建新线程来处理TCP连接:

t = threading.Thread(target=tcp_recv, args=(sock, addr))

t.start()

tcp_send(sock)

打开两个终端运行serve.py 和 client.py,运行结果应该是这样的:

服务端:

客户端:

原文地址:https://www.cnblogs.com/ustczjce/p/12024085.html

时间: 2024-10-01 02:18:55

以您熟悉的编程语言为例完成一个hello/hi的简单的网络聊天程序的相关文章

单例 实现 一个变量为 整个项目都可以用

单例究竟怎么传值?今天终于会了 .h @interface MySharedClass : NSObject @property (nonatomic, copy) NSString *sharedString; + (MySharedClass *)sharedInstance; @end .m @implementation MySharedClass + (MySharedClass *)sharedInstance { static MySharedClass *sharedInstan

以最简单的登录为例,诠释JS面向对象的简单实例

JavaScript,是前端开发人员必须会的一门技术,从JS演变出来的有很多框架,先说说几个热门的框架吧: JQuery:这个技术必须会,如果不会,那一定要会查api,知道怎么写,要看得懂英文文档,这个框架十分流行,不论是刚入坑的开发者还是老油条,其实也都是是需要会的 BackBone:这个技术还不错,曾经的项目中用到过多次,很方便,是个MVC的实用框架,用来渲染视图十分简便 AngularJS:是个MVVM框架,和JQuery完全不一样,JQuery是基于dom元素的,而angerlar却不是

[51单片机] 以PWM控制直流电机为例建一个简单的51工程框架

目录 1)功能概述 2)引脚连接 3)框架介绍 4)模块说明 5)复用规则 6)工程链接 1)功能概述 名称:独立按键控制直流电机调速 内容:对应的电机接口需用杜邦线连接到uln2003电机控制端; 使用5V-12V 小功率电机皆可 2个按键分别加速和减速; 采用8个8段数码管的后两位显示0~10级速度; 2)引脚连接 P3连接按键:P0连接8x八段数码管,P22段码锁存,P23位码锁存:P1.1连接ULN2003的一个输入:直流电机端连接ULN2003对应的输出,另一端连接VCC. 3)框架介

【峰回路转】Excel技巧百例 10.数据透视表的简单使用-分类汇总

在excel如何实现类似SQL SERVER中的group by的功能呢?在excel中可以使用透视表来完成这个工作. 原始数据: 假设这是某学校的学生成绩表(当然数据为很多,我们用少量数据演示这个功能) 如何快速得到每个学生的总分呢? 1.选中数据区域 2.点击上面的插入tab中的"数据透视表" 3.在弹出的窗口,点击确定 4.在新出现的窗口右侧将姓名放到行中,将分数拖拽到列中 5. 我们可以快速得到我们想要的结果,我们也可以把结果复制,然后选择性粘贴为数值,便于自己进行其他调整.

【峰回路转】Excel技巧百例 11.数据透视表的简单使用-行列转换

Excel的数据透视表不仅可以进行分类汇总,而且可以轻松快捷的进行行列转换 例如: 按照上篇文章中的方法我们可以插入数据透视表,将姓名放到行中,将课程放到列中,将分数放到值中: 从上面的结果中,我们可以清晰的看到有人缺考了英语 如果只显示姓名有重名的怎么办?是否可以把学号也显示出来呢?我们下一篇将介绍如何既显示学号,又显示姓名. 版权声明:本文为博主原创文章,未经博主允许不得转载.

一例对一个或多个实体的验证失败。有关详细信息,请参阅“EntityValidationErrors”属性的解决

这个问题相信只要是做MVC的,都碰到过,也都知道错误的原因,就是触发了定义的实例字段校验规则.比如定义的不为空,但是为空了,或者定义的字段长度为50,但是超过50了. 可是有时虽然知道是这样,但是具体问题解决的时候还是无从下手.我最近就碰到一个,知道是在更新某个表的时候出现的这个问题.可是在本地无法具现此错误,这个错误是在特定条件发生的,我并不知道此特定发生条件是什么,很郁闷. 在网上找了下,知道发生这个错误会触发DbEntityValidationException异常,这个异常会有详细的异常

java实现hello/hi的简单的网络聊天程序与ServerSocket调用栈跟踪

java实现hello/hi的简单的网络聊天程序 网络聊天采用TCP协议通过java实现 import java.io.*; import java.net.Socket; public class Client { public static void main(String[] args) throws Exception{ Socket socket = new Socket("192.168.31.68", 6666); BufferedReader reader = new

[Java 进阶]Java中的国际化

背景知识 现代软件开发,往往做出的应用程序不止给一个国家的人去使用.不同国家的人往往存在语言文字不通的问题.由此产生了国际化(internationalization).多语言(multi-language).本地化(locale)这些词,它们其实都是一个意思,支持多种语言,提供给不同国家的用户使用. 语言编码.国家/地区编码 做web 开发的朋友可能多多少少接触过类似 zh-cn, en-us 这样的编码字样. 这些编码是用来表示指定的国家地区的语言类型的.那么,这些含有特殊含义的编码是如何产

程序猿技术练级攻略

伯乐人才网6月9日发表了<写给即将入行的程序猿的一封信>,翻译自<An open letter to those who want to start programming>.我的朋友(他在本站的id是Mailper)告诉我,他希望在酷壳上看到一篇更具操作性的文章. 由于他也是喜欢编程和技术的家伙.于是,我让他把他的一些学习Python和Web编程的一些点滴总结一下.于是他给我发来了一些他的心得和经历,我在把他的心得做了不多的增改,并依据我的经历添加了"进阶"一