Python网络编程

查看Python中支持的编码方式:https://docs.python.org/3/library/codecs.html?highlight=utf

IP地址工具:http://ipblock.chacuo.net/

查看应用程序进程PID:

1.启动任务管理器,点击进程:默认是这样的:

2.点击查看, 选择列,勾上PID即可。

进程PID与进程使用的端口号是不同的概念。

Windows下看看哪个端口被占用及占用的进程

命令:

netstat -aon | findstr "8080"
netstat -an#查看所有的端口使用情况

8080是要查看的端口号。

例如在pycharm中建立一个网络通信

TCP

#time_server.py
import socket
import time
HOST = '127.0.0.1'
PORT = 12345
BUFSIZE = 1024
ADDR = (HOST,PORT)
tcpServerSock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
tcpServerSock.bind(ADDR)
tcpServerSock.listen(5)while True:print("waiting for connection...")#这里tcpClietnSock为<socket.socket fd=932, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 12345), raddr=('127.0.0.1', 64764)>,包含了socket的信息tcpClientSock,addr = tcpServerSock.accept()print("...connected from:",addr)while True:data = tcpClientSock.recv(BUFSIZE)if not data:break# tcpClientSock.send('[%s] %s'%(time.ctime().encode('utf-8'),str(data).encode('utf-8')))# tcpClientSock.send('%s %s'%(time.ctime().encode('utf-8'),data))tcpClientSock.send(bytes("[%s] %s"%(time.ctime(),data.decode('utf-8')),encoding='utf-8'))tcpClientSock.close()
#time_client.py
import socket
HOST = '127.0.0.1'
PORT = 12345
BUFSIZE = 1024
ADDR = (HOST,PORT)tcpClientSock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
tcpClientSock.connect(ADDR)while True:data = input('>')if not data:breaktcpClientSock.send(bytes(data,encoding='utf-8'))# tcpClientSock.send(data.encode('utf-8'))data = tcpClientSock.recv(BUFSIZE)if not data:breakprint(data.decode('utf-8'))
tcpClientSock.close()

 服务器端使用的端口好为:12345,运行服务器和客户端后,发现客户端使用的端口号为12037,执行命令:

查看到端口12345和12037被占用了,在任务管理其中查看到是Python3占用了这两个端口

为什么使用端口,而不直接使用PID了?

PID也可以唯一表示一个进程呀,这是因为使用PID代价太大,双方通信之前,得需要提前知道对方的PID,但是PID是操作系统自动分配的,人工去查很麻烦。如果直接使用端口的话比较方便,一般一个服务的端口比较固定。

同一个系统中,端口不能重复。

通信调试助手:模拟发送和接收情况。链接:https://pan.baidu.com/s/1GJTYxvUKGIHB9KM-D0CVug 密码:31z1

TCP连接中listen参数问题:

连接队列长度:客户端已经和服务器建立连接,或者客户端正在和服务器建立连接,但是还没有被服务器accept的最大个数。即同时等待accept的个数,和已经accept的个数没有关系。

Windows和Mac中严格安装这个参数来,Linux中内核会自己处理。

服务器

from socket import *
import times = socket(AF_INET,SOCK_STREAM)
s.bind(("127.0.0.1",12345))
s.listen(5)#队列缓存while True:clientScoket,addr = s.accept()print(addr)time.sleep(1)

客户端

from socket import *for i in range(10):c = socket(AF_INET, SOCK_STREAM)c.connect(("127.0.0.1",12345))#客户端只管啪啪啪connect,等连不上就报错print(i)

服务器端处理过慢,可能导致客户端连接超时报错。

本地的进程间通信:

网络间通信:socket

AF_UNIX本地通信
AF_INETIPv6
AF_NETLINK 
  
SOCK_STREAMTCP
SOCK_DGRAMUDP

UDP在局域网中几乎不会丢包

Python3中发送数据需要bytes类型,不能是字符串类型,不然会报错:

发送前将字符串编码,接收后将字符串解码。

中文一般是UTF-8,或者gb2312。

data='hello world'
data.encode('utf-8')
b'hello world'
bytes(data,encoding='utf-8')
b'hello world'
data='黄铁牛'
data.encode('utf-8')
b'\xe9\xbb\x84\xe9\x93\x81\xe7\x89\x9b'
bytes(data,encoding='utf-8')
b'\xe9\xbb\x84\xe9\x93\x81\xe7\x89\x9b'

UDP简单示例

服务器:

#服务器
from socket import *
import time
def main():udpServerSocket = socket(AF_INET,SOCK_DGRAM)#这里服务器可以绑定自己的ip地址和端口号,ip地址一般为空,表示本机的所有可用ip地址,#可以是网络地址,本地地址和127.0.0.1udpServerSocket.bind(("",12346))BUFFERSIZE = 1024#单位字节while True:print("..waiting for message:")data,addr = udpServerSocket.recvfrom(BUFFERSIZE)print("[%s] %s received from %s"%(time.ctime(),data.decode('utf-8'),addr))udpServerSocket.sendto(bytes("[%s] %s"%(time.ctime(),data.decode('utf-8')),encoding='utf-8'),addr)if __name__ == "__main__":main()

客户端:

#客户端
from socket import *
udpClientSock = socket(AF_INET,SOCK_DGRAM)
#这里客户端可以绑定自己的ip地址和端口号,ip地址一般为空,表示本机的所有可用ip地址,
#可以是网络地址,本地地址和127.0.0.1。这样以后客户端的端口号就不变了。
#客户端一般不绑定端口
#udpClientSock.bind(('',9999))#不能这里绑网络地址,下面发送给本地地址。
BUFFERSIZE = 1024
while True:data = input('>')if not data:breakudpClientSock.sendto(data.encode('utf-8'),("172.24.55.11",12346))data,ADDR = udpClientSock.recvfrom(BUFFERSIZE)if not data:breakprint(data.decode('utf-8'))
udpClientSock.close()

 

 
 

udp模拟QQ聊天,多线程,两边同时接收,发送

#服务器
from threading import Thread
from socket import *
import time
BUFFERSIZE = 1024#接收数据,打印
def receive_data():global dest_addrwhile True:data,addr = udpSocket.recvfrom(BUFFERSIZE)dest_addr = addrprint("\r>>[%s] receive %s from %s\n<<"%(time.ctime(),data.decode('utf-8'),addr),end='')def send_data():while True:data = input("<<")udpSocket.sendto(data.encode('utf-8'),dest_addr)udpSocket = None#一般空对象为None,空字符串为''
dest_addr = Nonedef main():global udpSocketudpSocket = socket(AF_INET,SOCK_DGRAM)udpSocket.bind(('',45678))receive_thread = Thread(target=receive_data)send_thread = Thread(target=send_data)receive_thread.start()send_thread.start()receive_thread.join()send_thread.join()if __name__ == '__main__':main()
#客户端
from threading import Thread
from socket import *
import time
BUFFERSIZE = 1024#接收数据,打印
def receive_data():while True:data,addr = udpSocket.recvfrom(BUFFERSIZE)print("\r>>[%s] receive %s from %s\n<<"%(time.ctime(),data.decode('utf-8'),addr),end='')#发送数据
def send_data():while True:data = input("<<")udpSocket.sendto(data.encode('utf-8'),('127.0.0.1',45678))udpSocket = None#一般空对象为None,空字符串为''def main():global udpSocketudpSocket = socket(AF_INET,SOCK_DGRAM)udpSocket.bind(('', 45679))receive_thread = Thread(target=receive_data)send_thread = Thread(target=send_data)receive_thread.start()send_thread.start()receive_thread.join()send_thread.join()if __name__ == '__main__':main()

 

udpSocketClient.recvfrom(1024)报错问题:

参考:https://stackoverflow.com/questions/35805664/socket-recvfrom1024-throws-socket-error-invalid-argument-supplied#

data,addr = udpSocketClient.recvfrom(BUFFERSIZE)
OSError: [WinError 10022] 提供了一个无效的参数。

在客户端接收数据之前,操作系统需要知道该进程的端口号,才能将数据发送给客户端。所以不能一上来就直接接收,需要先给客户端帮一个端口udpSocketClient.bind('ip',port)或者先让客户端发数据udpSocketClient.send(data,('destip',port)),这样客户端先发数据后,系统就会自动给客户端分配一个端口,这样客户端就能够接收数据了。

UDP广播

TCP没有广播,

import socket
import time
#这里的broadcast表示受限的广播地址,也可以直接写广播地址
# dest = ('<broadcast>',8080)
dest = ('172.24.54.255',8080)s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
#如果想要发送广播数据,需要对套接字进行设置,才能发送广播数据,否则不能发送广播数据
s.setsockopt(socket.SOL_SOCKET,socket.SO_BROADCAST,1)s.sendto("Hi".encode('utf-8'),dest)
print("等待对方回复")while True:data,address = s.recvfrom(2048)print("[%s] received from %s:%s"%(time.ctime(),address,data.decode('utf-8')))

Cisco packet tracer

下载:链接:https://pan.baidu.com/s/1OaJtyCIv1nJvMVcUhS-Cfw 密码:h6os

arp -a查看IP地址和Mac地址对应情况

arp -d清空本地缓存的IP地址和Mac地址对应信息

路由器配置:

配置主机IP地址,子网掩码,默认网关,配置路由器IP地址,子网掩码,静态路由,开启路由器端口。

A网段a和B网段b通信:

看a有没有默认网关,没有直接挂,

a通过arp解析网关的Mac地址

A将信息发给A的网关

A的网关将信息根据路由表发给下一跳路由器(不知道Mac地址的话,arp解析)

...

访问网页过程:

1.DNS域名解析

看主机PC7有没有设置默认网关,没有直接挂

如果不知道默认网关的Mac地址,就arp解析默认网关的Mac地址

主机PC7发送DNS请求解析数据给默认网关,网关转发给其他路由器,直到目的DNS服务器的默认网关,

DNS服务器的网关如果不知道DNS服务器的Mac地址,同样arp解析DNS服务器Mac地址

DNS网关将DNS请求解析数据发给DNS服务器

DNS服务器解析后,将数据返回给原主机PC7

2.主机PC和HTTP服务器TCP三次握手

3.http报文传输

4.tcp4次挥手。

TCP短连接:

每发送一次数据就要进行三次握手,四次挥手:TCP握手,发送数据,TCP四次挥手。。。TCP握手,发送数据,TCP四次挥手。应用:web应用,在HTTP/1.0中,默认使用的是短连接

TCP长连接

建立一个连接后,只要没有显式关闭连接,就一直发送数据:TCP三次握手,发送数据,发送数据,TCP四次挥手。旨在建立 1 次 TCP 连接后进行多次请求和响应的交互。应用:看视频; HTTP/1.1起,默认使用长连接

备注:HTTP的长连接与短连接,本质上就是TCP的长连接与短连接。

 

TCP十种状态

常见网络攻击:

DoS(Denial of Service,拒绝服务)攻击

利用TCP三次握手漏洞,客户端在发送SYN,并且收到SYN+ACK后,迟迟不发送ACK,让服务器一直等待。例如,我一台电脑开十个进程,一个进程开十个线程攻击某个网站。占用它的listen队列,使其他人不能正常访问。

DNS攻击

DNS服务器被劫持:

攻击DNS服务器,修改域名对应的ip,当用户访问某个网站时,跳转到其他的页面,例如广告,钓鱼网站。钓鱼网站先把别的网站例如淘宝的网页类容down下来,做一个和淘宝一模一样的界面,用户以为是真的淘宝,输入用户名,密码,信息就被获取了。

DNS服务器常常是重兵把守,

DNS欺骗:

用户在向DNS服务器请求域名解析的时候,攻击者⽤⼀个假的 DNS 应答来欺骗⽤户计算机,给它一个加的域名,IP对应。

Client的DNS查询请求和DNS Server的应答数据包是依靠DNS报文的ID标识来相互对应的。在进行域名解析时,Client首先用特定的ID号向DNS Server发送域名解析数据包,这个ID是随机产生的。DNS Server找到结果后使用此ID给Client发送应答数据包。Client接收到应答包后,将接收到的ID与请求包的ID对比,如果相同则说明接收到的数据包是自己所需要的,如果不同就丢弃此应答包。根据攻击者的查询和应答原理,可使用不同方法实现攻击,如:

      (1)因为DNS Message仅使用一个简单的认证码来实施真实性验证,认证码是由Client程序产生并由DNS Server返回结果的,客户机只是使用这个认证码来辨别应答与申请查询是否匹配,这就使得针对ID认证码的攻击威胁成为可能。

arp攻击

攻击值攻击通信的双方,让他们的目的ip地址对应的Mac地址都是自己的,这样攻击者就可以接收到信息,接收到信息之后,为了不被发现,存储下来之后,再发送出去。

NAT

家里上网,就分配了一个公网ip地址,猫下面连路由器,路由器下面接电脑,手机。电脑,手机访问外网,通过了网络地址转换。

单进程服务器:(没啥实际应用)

服务器:

from socket import *
serverScoket = socket(AF_INET,SOCK_STREAM)
serverScoket.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)#让服务器意外结束时不能等待2MSL时间,就可以立即使用该端口
serverScoket.bind(("127.0.0.1",12345))
serverScoket.listen(5)while True:clientScoket,addr = serverScoket.accept()print("serve for:",addr)try:while True:data = clientScoket.recv(1024)if len(data)>0:print("receve %s from %s"%(data.decode('utf-8'),addr))else:print("%s客户端已关闭"%(addr))breakexcept:passfinally:clientScoket.close()serverScoket.close()

客户端:

from socket import *
clientSocket = socket(AF_INET,SOCK_STREAM)
clientSocket.connect(("127.0.0.1",12345))while True:data = input("please input the data:")if len(data)>0:clientSocket.send(data.encode('utf-8'))else:break
clientSocket.close()

同一时刻只能为一个用户服务,当服务器为一个客户服务时,而另外的新客户进行连接,只要服务器listen队列有空闲的位置,就会为这个新客户端进行连接,并且客户端可以发送数据,但当服务器为这个新客户端服务时,可能一次性把所有数据接收完毕。

多进程服务器:

服务器端:

from socket import *
from multiprocessing import *
#处理客户端的请求并为其服务
def dealWithClient(clientScoket,addr):while True:try:data = clientScoket.recv(1024)except:print("%s客户端已关闭" % (str(addr)))#客户端直接X掉关闭breakif len(data) > 0:print("receve %s from %s" % (data.decode('utf-8'), addr))else:print("%s客户端已关闭" % (str(addr)))breakclientScoket.close()def main():serverScoket = socket(AF_INET, SOCK_STREAM)serverScoket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)  # 让服务器意外结束时不能等待2MSL时间,就可以立即使用该端口serverScoket.bind(("127.0.0.1", 12345))serverScoket.listen(5)try:while True:clientSocket,addr = serverScoket.accept()# print(addr,type(addr))#add是一个元组print("serve for %s"%(str(addr)))client = Process(target=dealWithClient,args=(clientSocket,addr))client.start()#子进程已经copy了一份,这里可以关闭clientSocket.close()except:passfinally:serverScoket.close()if __name__ == '__main__':main()

多线程服务器:

服务器端

from socket import *
from threading import  Thread
import time
#处理客户端的请求并为其服务
def dealWithClient(clientScoket,addr):while True:try:data = clientScoket.recv(1024)except:print("%s客户端已关闭" % (str(addr)))breakif len(data) > 0:print("receve %s from %s" % (data.decode('utf-8'), addr))else:print("%s客户端已关闭" % (str(addr)))breakclientScoket.close()def main():serverScoket = socket(AF_INET, SOCK_STREAM)serverScoket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)  # 让服务器意外结束时不能等待2MSL时间,就可以立即使用该端口serverScoket.bind(("127.0.0.1", 12345))serverScoket.listen(5)try:while True:time.sleep(5)clientSocket,addr = serverScoket.accept()# print(addr,type(addr))#add是一个元组print("serve for %s"%(str(addr)))client = Thread(target=dealWithClient,args=(clientSocket,addr))client.start()#线程中共享这个套接字,这里不能关闭# clientSocket.close()except:passfinally:serverScoket.close()if __name__ == '__main__':main()

单进程服务器_非阻塞

from socket import  *clientSocketList = []def main():serverSocket = socket(AF_INET,SOCK_STREAM)serverSocket.bind(('127.0.0.1',12345))serverSocket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)serverSocket.listen(5)# 将套接字设置为非阻塞,这样就不会卡在accept处了serverSocket.setblocking(False)while True:try:clientSocket,addr = serverSocket.accept()except :passelse:print("一个新客户端到来:%s"%str(addr))#将clientSocket设置为非阻塞,在recv处就不阻塞了clientSocket.setblocking(False)clientSocketList.append((clientSocket,addr))for clientSocket,addr in clientSocketList:try:data = clientSocket.recv(1024)except BlockingIOError:passexcept ConnectionResetError:clientSocket.close()clientSocketList.remove((clientSocket, addr))print("%s已经下线" % str(addr))breakelse:if len(data)>0:print("%s:%s"%(str(addr),data.decode('utf-8')))else:clientSocket.close()clientSocketList.remove((clientSocket,addr))print("%s已经下线"%str(addr))if __name__ == '__main__':main()

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/353144.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

Redis的安装等相关问题

1.1 下载 从官网下载&#xff0c;Redis官网点击下载 或者直接下载整合下好的&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1Vj9jNq2mh5lZLVFSVo5cFw&shflsharepset 提取码&#xff1a;m599 通过SecureCRT将下载的文件上传到/opt/work目录 如果上传rz不能使用…

路由器 ------ 动态路由 (1) ---- RIP

RIP &#xff1a; 根据Bellman-Ford算法计算路由 距离矢量型协议&#xff08;DV&#xff09;---- 路由器之间传递路由条目 &#xff1b;距离就是开销值&#xff0c;矢量就是下一跳 邻居关系 ---- 相邻的两个路由器&#xff0c;链接在共同的广播域内&#xff0c;通过广播的形…

华为云HCS解决方案笔记HUAWEI CLOUD Stack【面试篇】

目录 HCS方案 一、定义 1、特点 2、优点 二、云服务 1、云管理 2、存储服务 3、网络服务 4、计算服务 5、安全服务 6、灾备服务 7、容器服务 三、应用场景 四、HCS功能层 五、OpenStack网络平面规划 六、ManageOne运维面 1、首页 2、集中监控 3、资源拓扑 …

关于Arthas如何远程监视Java程序

在使用 Arthas 之前&#xff0c;当遇到 Java 线上问题时&#xff0c;如 CPU 飙升、负载突高、内存溢出等问题&#xff0c;你需要查命令&#xff0c;查网络&#xff0c;然后 jps、jstack、jmap、jhat、jstat、hprof 等一通操作。最终焦头烂额&#xff0c;还不一定能查出问题所在…

NLP+VS︱深度学习数据集标注工具、图像语料数据库、实验室搜索ing...

~~因为不太会使用opencv、matlab工具&#xff0c;所以在找一些比较简单的工具。 . 一、NLP标注工具 来源&#xff1a;《构想&#xff1a;中文文本标注工具&#xff08;附开源文本标注工具列表&#xff09;》 Chinese-Annotator 来源&#xff1a;https://github.com/crownpku/…

kube-proxy源码阅读(iptables实现)

Reference 文章目录 1 入口2 ProxyServer创建及调用3 ProxyServer 核心调用流程3.1 func (o *Options) Run() err3.2 func (o *Options) runLoop() error3.3 func (s *ProxyServer) Run() error3.4 func (proxier *Proxier) SyncLoop() 4 资源事件处理流程4.1 Service事件4.2 …

windows_删除多余网络适配器(删除/卸载多余网卡)/删除TAP虚拟网卡NIC

文章目录 Device Manager检查所有NIC状态利用资源监视器查看网卡情况接入不同网络对于计算机网络环境造成不同的影响接入传统的wifi接入手机热点的wifi Device Manager 删除指定的Network adapter(网卡又称为网络适配器)完成之后你可能需要重启才可以上网 检查所有NIC状态 包…

值得一阅的Kali系统的使用小技巧

目录 写在最前1.软件安装软件源关于AMD显卡驱动浏览器中文输入法下载工具代理软件QQSteam 2.使用优化ssh服务开启Grub修改Zsh和PowerShell命令标头修改VSCode内置终端字体间距过大问题 Aria2配置文件 写在最前 不定期更新 1.软件安装 软件源 推荐使用中科大源&#xff0c;官…

基于geoserver开发地图发布服务

写在前面&#xff1a;我在github上创建了对应的项目&#xff0c;可点此跳转&#xff0c;本文的所有源码均可在项目里找到&#xff0c;欢迎大家访问交流 一、开发背景 在gis领域&#xff0c;geoserver是后端地图发布的开源项目。目前我们在启动服务后&#xff0c;可通过自带的…

CIPSTAT

AT_TCPIP_CmdFunc_CIPSTART //start up tcpip connection 1&#xff09;if (gCipBearer ! BEARER_WIFI) 承载是GPRS(1)还是WIFI&#xff08;2&#xff09;&#xff0c;若非WIFI&#xff0c;获取SimStatus 2)if ((!cipMux_multiIp && (CIP_INITIALg_uCipContexts.nBeare…

Cloud Computing:云计算的简介、必要性以及安全上云与企业数字化转型(从陈坤/辛芷蕾主演电视剧《输赢》看云计算的未来)的关系

Cloud Computing&#xff1a;云计算的简介、必要性以及安全上云与企业数字化转型(从陈坤/辛芷蕾主演电视剧《输赢》看云计算的未来)的关系 目录 云计算的简介、必要性以及安全上云与企业数字化转型(从陈坤/辛芷蕾主演电视剧《输赢》看云计算的未来)的关系 从陈坤/辛芷蕾主演电…

relation-graph关系图谱组件2.0版本遇到的问题

前提&#xff1a;之前已经写过一篇1.1版本的问题&#xff0c;这里就不过多讲了&#xff08;如果想要解决火狐低版本兼容&#xff0c;看那个就行&#xff09; 这次主要讲的是和1.X版本的区别和一些其它问题 区别 参数名不同&#xff1a;以前的links>lines (虽然现在links也…

高压放大器在微流控技术的应用研究

随着微流控技术的不断发展&#xff0c;其在生物医学、环境监测、化学分析等领域中的应用越来越广泛&#xff0c;也对相关器件的性能提出了更高的要求。其中&#xff0c;高压放大器作为一种电子元器件&#xff0c;在微流控技术中具有重要的作用。下面安泰电子将从高压放大器在微…

仙境传说RO:添加商店物品教程

仙境传说RO&#xff1a;添加商店物品教程 我是艾西&#xff0c;今天跟大家分享下仙境传说RO游戏中我们自己怎么创建商店卖东西装备等&#xff0c;首先看看下图以及自己创建商店时需要在文档里创建的脚本格式 //*------------------shop普通商店------------------ //带坐标的…

Java养成类小游戏

此周是做项目 做一个java的养成类的小游戏 我是用控制台写的小游戏 建了很多的UI地图&#xff0c;部分代码&#xff0c; 然后让我们来看实现的样子&#xff1a; 好啦&#xff0c;部分内容就到这啦 早点洗洗睡叭&#xff01;

Java游戏合集

游戏1&#xff1a;猜数字小游戏&#xff1a; import java.util.Scanner; class GuessNumber{public static void main(String args[]){int number (int)(Math.random()*100)1;System.out.println("请输入一个数据&#xff08;1-100&#xff09;用于猜数字。");whil…

JAVA学习之路-简单的城堡游戏(一)

简单的文字城堡游戏&#xff08;一&#xff09; 最近在学习后台的一些功能&#xff0c;发现自己的基础不是很牢固&#xff0c;所以想写点小程序&#xff0c;巩固一下以前学的知识&#xff0c;融合一下。 之前在慕课上学的课程中就有一个这样的小程序&#xff0c;写一个简单的…

Nginx的优化,安全与防盗链

目录 一、Nginx的页面优化 1&#xff09;Nginx的网页压缩 2&#xff09;配置Nginx的图片缓存 3&#xff09;Nginx的连接超时设置 4&#xff09;Nginx的并发设置 查看cpu的核心数&#xff0c;根据核心数来设置工作进程数 修改工作进程核心数 &#xff1a; 测试结果&…

java做RPG小游戏

题目 java课设&#xff0c;一个游戏中有多种角色(Character)&#xff0c;例如&#xff1a;国王&#xff08;King&#xff09;、皇后&#xff08;Queen&#xff09;、骑士&#xff08;Knight&#xff09;、老怪&#xff08;Troll&#xff09;。 角色之间可能要发生战斗(fight)&…

【Java游戏合集】手把手教你制作游戏

家人们&#xff0c;今天我们来看一下学Java必练的10款游戏项目&#xff01; 大家都知道学习编程必须要做的就是敲代码和做项目练手了&#xff0c;那项目有难有易&#xff0c;很多小伙伴不知道从哪里找项目来练习&#xff0c;今日我们来看一下初级项目中都有哪些能让我们来练手…