├── 2021PPT ├── DS-CH-1-2021.pdf ├── DS-CH-10.pdf ├── DS-CH-11-Hadoop.pdf ├── DS-CH-2-2021.pdf ├── DS-CH-3-2021.pdf ├── DS-CH-4-2021.pdf ├── DS-CH-5-2021.pdf ├── DS-CH-5-命名-Nov09.pdf ├── DS-CH-6-协同-Nov12.pdf ├── DS-CH-7-全.pdf ├── DS-CH-8-容错.pptx └── DS-CH-9-ConProto-Dec12.pptx ├── 2021作业 ├── 18329015_郝裕玮_hw1 │ ├── 18329015_郝裕玮_hw1.docx │ ├── 18329015_郝裕玮_hw1.pdf │ └── 作业-1.pdf ├── 18329015_郝裕玮_hw2 │ ├── 18329015_郝裕玮_hw2.docx │ ├── 18329015_郝裕玮_hw2.pdf │ └── 作业-2-2021.pdf ├── 18329015_郝裕玮_hw3 │ ├── 18329015_郝裕玮_hw3 │ │ ├── 18329015_郝裕玮_hw3.docx │ │ ├── 18329015_郝裕玮_hw3.pdf │ │ └── proto │ │ │ ├── __pycache__ │ │ │ ├── msg_pb2.cpython-37.pyc │ │ │ └── msg_pb2_grpc.cpython-37.pyc │ │ │ ├── client.py │ │ │ ├── msg.proto │ │ │ ├── msg_pb2.py │ │ │ ├── msg_pb2_grpc.py │ │ │ └── server.py │ └── 作业-3-2021.pdf ├── 18329015_郝裕玮_hw5 │ ├── 18329015_郝裕玮_hw5 │ │ ├── 18329015_郝裕玮_hw5.docx │ │ ├── 18329015_郝裕玮_hw5.pdf │ │ └── reliable-multicast-chat-master │ │ │ ├── .gitignore │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── bin │ │ │ └── reliable_multicast_chat │ │ │ └── reliable_multicast_chat │ │ │ ├── __init__.py │ │ │ ├── chat_process.py │ │ │ ├── config.py │ │ │ ├── helpers │ │ │ └── unicast_helper.py │ │ │ └── main.py │ └── 作业-5.pdf ├── 18329015_郝裕玮_hw6 │ ├── 18329015_郝裕玮_hw6 │ │ ├── 18329015_郝裕玮_hw6.docx │ │ ├── 18329015_郝裕玮_hw6.pdf │ │ └── proto │ │ │ ├── __pycache__ │ │ │ ├── msg_pb2.cpython-37.pyc │ │ │ └── msg_pb2_grpc.cpython-37.pyc │ │ │ ├── client.py │ │ │ ├── msg.proto │ │ │ ├── msg_pb2.py │ │ │ ├── msg_pb2_grpc.py │ │ │ ├── server1.py │ │ │ ├── server2.py │ │ │ └── server3.py │ └── 作业-6-一致性与复制.pdf ├── 18329015_郝裕玮_大作业 │ ├── 18329015_郝裕玮_计科1班.docx │ ├── 18329015_郝裕玮_计科1班.pdf │ ├── test │ │ ├── client.py │ │ ├── database.sqlite │ │ ├── middle.py │ │ ├── server.py │ │ └── user.txt │ └── 功能测试.mp4 └── 分布式系统作业模板.docx ├── README.md └── 教材 └── 分布式系统原理与范型 第二版.pdf /2021PPT/DS-CH-1-2021.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021PPT/DS-CH-1-2021.pdf -------------------------------------------------------------------------------- /2021PPT/DS-CH-10.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021PPT/DS-CH-10.pdf -------------------------------------------------------------------------------- /2021PPT/DS-CH-11-Hadoop.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021PPT/DS-CH-11-Hadoop.pdf -------------------------------------------------------------------------------- /2021PPT/DS-CH-2-2021.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021PPT/DS-CH-2-2021.pdf -------------------------------------------------------------------------------- /2021PPT/DS-CH-3-2021.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021PPT/DS-CH-3-2021.pdf -------------------------------------------------------------------------------- /2021PPT/DS-CH-4-2021.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021PPT/DS-CH-4-2021.pdf -------------------------------------------------------------------------------- /2021PPT/DS-CH-5-2021.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021PPT/DS-CH-5-2021.pdf -------------------------------------------------------------------------------- /2021PPT/DS-CH-5-命名-Nov09.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021PPT/DS-CH-5-命名-Nov09.pdf -------------------------------------------------------------------------------- /2021PPT/DS-CH-6-协同-Nov12.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021PPT/DS-CH-6-协同-Nov12.pdf -------------------------------------------------------------------------------- /2021PPT/DS-CH-7-全.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021PPT/DS-CH-7-全.pdf -------------------------------------------------------------------------------- /2021PPT/DS-CH-8-容错.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021PPT/DS-CH-8-容错.pptx -------------------------------------------------------------------------------- /2021PPT/DS-CH-9-ConProto-Dec12.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021PPT/DS-CH-9-ConProto-Dec12.pptx -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_hw1/18329015_郝裕玮_hw1.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021作业/18329015_郝裕玮_hw1/18329015_郝裕玮_hw1.docx -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_hw1/18329015_郝裕玮_hw1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021作业/18329015_郝裕玮_hw1/18329015_郝裕玮_hw1.pdf -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_hw1/作业-1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021作业/18329015_郝裕玮_hw1/作业-1.pdf -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_hw2/18329015_郝裕玮_hw2.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021作业/18329015_郝裕玮_hw2/18329015_郝裕玮_hw2.docx -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_hw2/18329015_郝裕玮_hw2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021作业/18329015_郝裕玮_hw2/18329015_郝裕玮_hw2.pdf -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_hw2/作业-2-2021.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021作业/18329015_郝裕玮_hw2/作业-2-2021.pdf -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_hw3/18329015_郝裕玮_hw3/18329015_郝裕玮_hw3.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021作业/18329015_郝裕玮_hw3/18329015_郝裕玮_hw3/18329015_郝裕玮_hw3.docx -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_hw3/18329015_郝裕玮_hw3/18329015_郝裕玮_hw3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021作业/18329015_郝裕玮_hw3/18329015_郝裕玮_hw3/18329015_郝裕玮_hw3.pdf -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_hw3/18329015_郝裕玮_hw3/proto/__pycache__/msg_pb2.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021作业/18329015_郝裕玮_hw3/18329015_郝裕玮_hw3/proto/__pycache__/msg_pb2.cpython-37.pyc -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_hw3/18329015_郝裕玮_hw3/proto/__pycache__/msg_pb2_grpc.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021作业/18329015_郝裕玮_hw3/18329015_郝裕玮_hw3/proto/__pycache__/msg_pb2_grpc.cpython-37.pyc -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_hw3/18329015_郝裕玮_hw3/proto/client.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import grpc 3 | import msg_pb2 4 | import msg_pb2_grpc 5 | 6 | def run(): 7 | # 客户端很好理解,网络连接得到一个channel,拿channel去实例化一个stub,通过stub调用RPC函数 8 | channel = grpc.insecure_channel('localhost:50051') 9 | # 使用grpc.insecure_channel('localhost:50051')进行连接服务端,接着在这个channel上创建stub 10 | stub = msg_pb2_grpc.MsgServiceStub(channel) 11 | # 在msg_pb2_grpc里可以找到MsgServiceStub这个类相关信息。这个stub可以调用远程的GetMsg函数 12 | 13 | a1 = float(input());# 输入运算数1,并转为float型 14 | op1 = input();# 输入运算符号类型 15 | b1 = float(input());# 输入运算数2,并转为float型 16 | 17 | response = stub.GetMsg(msg_pb2.MsgRequest(a=a1,op=op1,b=b1))# response为服务器端发来的内容 18 | # MsgRequest中的内容即msg.proto中定义的数据。在回应里可以得到msg.proto中定义的msg 19 | 20 | msg = "服务器端运算结果为:{}\n".format(response.result)#打印从服务器端接收到的数据,即运算结果 21 | print(msg) 22 | 23 | if __name__ == '__main__': 24 | run() -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_hw3/18329015_郝裕玮_hw3/proto/msg.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | //规定语法,这里使用的是proto3的语法 3 | //使用service关键字定义服务 4 | 5 | service MsgService { 6 | rpc GetMsg (MsgRequest) returns (MsgResponse){} 7 | //简单RPC,即客户端发送一个请求给服务端,从服务端获取一个应答,就像一次普通的函数调用 8 | } 9 | 10 | //定义message内部需要传递的数据类型 11 | message MsgRequest { 12 | float a = 1; //运算数1 13 | string op = 2;//运算符号 14 | float b = 3; //运算数2 15 | //消息定义中,每个字段都有唯一的一个数字标识符 16 | //这些标识符是用来在消息的二进制格式中识别各个字段的,一旦开始使用就不能够再改变 17 | } 18 | 19 | message MsgResponse { 20 | float result = 1;//算数结果 21 | } -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_hw3/18329015_郝裕玮_hw3/proto/msg_pb2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by the protocol buffer compiler. DO NOT EDIT! 3 | # source: msg.proto 4 | """Generated protocol buffer code.""" 5 | from google.protobuf import descriptor as _descriptor 6 | from google.protobuf import message as _message 7 | from google.protobuf import reflection as _reflection 8 | from google.protobuf import symbol_database as _symbol_database 9 | # @@protoc_insertion_point(imports) 10 | 11 | _sym_db = _symbol_database.Default() 12 | 13 | 14 | 15 | 16 | DESCRIPTOR = _descriptor.FileDescriptor( 17 | name='msg.proto', 18 | package='', 19 | syntax='proto3', 20 | serialized_options=None, 21 | create_key=_descriptor._internal_create_key, 22 | serialized_pb=b'\n\tmsg.proto\".\n\nMsgRequest\x12\t\n\x01\x61\x18\x01 \x01(\x02\x12\n\n\x02op\x18\x02 \x01(\t\x12\t\n\x01\x62\x18\x03 \x01(\x02\"\x1d\n\x0bMsgResponse\x12\x0e\n\x06result\x18\x01 \x01(\x02\x32\x33\n\nMsgService\x12%\n\x06GetMsg\x12\x0b.MsgRequest\x1a\x0c.MsgResponse\"\x00\x62\x06proto3' 23 | ) 24 | 25 | 26 | 27 | 28 | _MSGREQUEST = _descriptor.Descriptor( 29 | name='MsgRequest', 30 | full_name='MsgRequest', 31 | filename=None, 32 | file=DESCRIPTOR, 33 | containing_type=None, 34 | create_key=_descriptor._internal_create_key, 35 | fields=[ 36 | _descriptor.FieldDescriptor( 37 | name='a', full_name='MsgRequest.a', index=0, 38 | number=1, type=2, cpp_type=6, label=1, 39 | has_default_value=False, default_value=float(0), 40 | message_type=None, enum_type=None, containing_type=None, 41 | is_extension=False, extension_scope=None, 42 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 43 | _descriptor.FieldDescriptor( 44 | name='op', full_name='MsgRequest.op', index=1, 45 | number=2, type=9, cpp_type=9, label=1, 46 | has_default_value=False, default_value=b"".decode('utf-8'), 47 | message_type=None, enum_type=None, containing_type=None, 48 | is_extension=False, extension_scope=None, 49 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 50 | _descriptor.FieldDescriptor( 51 | name='b', full_name='MsgRequest.b', index=2, 52 | number=3, type=2, cpp_type=6, label=1, 53 | has_default_value=False, default_value=float(0), 54 | message_type=None, enum_type=None, containing_type=None, 55 | is_extension=False, extension_scope=None, 56 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 57 | ], 58 | extensions=[ 59 | ], 60 | nested_types=[], 61 | enum_types=[ 62 | ], 63 | serialized_options=None, 64 | is_extendable=False, 65 | syntax='proto3', 66 | extension_ranges=[], 67 | oneofs=[ 68 | ], 69 | serialized_start=13, 70 | serialized_end=59, 71 | ) 72 | 73 | 74 | _MSGRESPONSE = _descriptor.Descriptor( 75 | name='MsgResponse', 76 | full_name='MsgResponse', 77 | filename=None, 78 | file=DESCRIPTOR, 79 | containing_type=None, 80 | create_key=_descriptor._internal_create_key, 81 | fields=[ 82 | _descriptor.FieldDescriptor( 83 | name='result', full_name='MsgResponse.result', index=0, 84 | number=1, type=2, cpp_type=6, label=1, 85 | has_default_value=False, default_value=float(0), 86 | message_type=None, enum_type=None, containing_type=None, 87 | is_extension=False, extension_scope=None, 88 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 89 | ], 90 | extensions=[ 91 | ], 92 | nested_types=[], 93 | enum_types=[ 94 | ], 95 | serialized_options=None, 96 | is_extendable=False, 97 | syntax='proto3', 98 | extension_ranges=[], 99 | oneofs=[ 100 | ], 101 | serialized_start=61, 102 | serialized_end=90, 103 | ) 104 | 105 | DESCRIPTOR.message_types_by_name['MsgRequest'] = _MSGREQUEST 106 | DESCRIPTOR.message_types_by_name['MsgResponse'] = _MSGRESPONSE 107 | _sym_db.RegisterFileDescriptor(DESCRIPTOR) 108 | 109 | MsgRequest = _reflection.GeneratedProtocolMessageType('MsgRequest', (_message.Message,), { 110 | 'DESCRIPTOR' : _MSGREQUEST, 111 | '__module__' : 'msg_pb2' 112 | # @@protoc_insertion_point(class_scope:MsgRequest) 113 | }) 114 | _sym_db.RegisterMessage(MsgRequest) 115 | 116 | MsgResponse = _reflection.GeneratedProtocolMessageType('MsgResponse', (_message.Message,), { 117 | 'DESCRIPTOR' : _MSGRESPONSE, 118 | '__module__' : 'msg_pb2' 119 | # @@protoc_insertion_point(class_scope:MsgResponse) 120 | }) 121 | _sym_db.RegisterMessage(MsgResponse) 122 | 123 | 124 | 125 | _MSGSERVICE = _descriptor.ServiceDescriptor( 126 | name='MsgService', 127 | full_name='MsgService', 128 | file=DESCRIPTOR, 129 | index=0, 130 | serialized_options=None, 131 | create_key=_descriptor._internal_create_key, 132 | serialized_start=92, 133 | serialized_end=143, 134 | methods=[ 135 | _descriptor.MethodDescriptor( 136 | name='GetMsg', 137 | full_name='MsgService.GetMsg', 138 | index=0, 139 | containing_service=None, 140 | input_type=_MSGREQUEST, 141 | output_type=_MSGRESPONSE, 142 | serialized_options=None, 143 | create_key=_descriptor._internal_create_key, 144 | ), 145 | ]) 146 | _sym_db.RegisterServiceDescriptor(_MSGSERVICE) 147 | 148 | DESCRIPTOR.services_by_name['MsgService'] = _MSGSERVICE 149 | 150 | # @@protoc_insertion_point(module_scope) 151 | -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_hw3/18329015_郝裕玮_hw3/proto/msg_pb2_grpc.py: -------------------------------------------------------------------------------- 1 | # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! 2 | """Client and server classes corresponding to protobuf-defined services.""" 3 | import grpc 4 | 5 | import msg_pb2 as msg__pb2 6 | 7 | 8 | class MsgServiceStub(object): 9 | """Missing associated documentation comment in .proto file.""" 10 | 11 | def __init__(self, channel): 12 | """Constructor. 13 | 14 | Args: 15 | channel: A grpc.Channel. 16 | """ 17 | self.GetMsg = channel.unary_unary( 18 | '/MsgService/GetMsg', 19 | request_serializer=msg__pb2.MsgRequest.SerializeToString, 20 | response_deserializer=msg__pb2.MsgResponse.FromString, 21 | ) 22 | 23 | 24 | class MsgServiceServicer(object): 25 | """Missing associated documentation comment in .proto file.""" 26 | 27 | def GetMsg(self, request, context): 28 | """Missing associated documentation comment in .proto file.""" 29 | context.set_code(grpc.StatusCode.UNIMPLEMENTED) 30 | context.set_details('Method not implemented!') 31 | raise NotImplementedError('Method not implemented!') 32 | 33 | 34 | def add_MsgServiceServicer_to_server(servicer, server): 35 | rpc_method_handlers = { 36 | 'GetMsg': grpc.unary_unary_rpc_method_handler( 37 | servicer.GetMsg, 38 | request_deserializer=msg__pb2.MsgRequest.FromString, 39 | response_serializer=msg__pb2.MsgResponse.SerializeToString, 40 | ), 41 | } 42 | generic_handler = grpc.method_handlers_generic_handler( 43 | 'MsgService', rpc_method_handlers) 44 | server.add_generic_rpc_handlers((generic_handler,)) 45 | 46 | 47 | # This class is part of an EXPERIMENTAL API. 48 | class MsgService(object): 49 | """Missing associated documentation comment in .proto file.""" 50 | 51 | @staticmethod 52 | def GetMsg(request, 53 | target, 54 | options=(), 55 | channel_credentials=None, 56 | call_credentials=None, 57 | insecure=False, 58 | compression=None, 59 | wait_for_ready=None, 60 | timeout=None, 61 | metadata=None): 62 | return grpc.experimental.unary_unary(request, target, '/MsgService/GetMsg', 63 | msg__pb2.MsgRequest.SerializeToString, 64 | msg__pb2.MsgResponse.FromString, 65 | options, channel_credentials, 66 | insecure, call_credentials, compression, wait_for_ready, timeout, metadata) 67 | -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_hw3/18329015_郝裕玮_hw3/proto/server.py: -------------------------------------------------------------------------------- 1 | from concurrent import futures 2 | import time 3 | import grpc 4 | import msg_pb2 5 | import msg_pb2_grpc 6 | _ONE_DAY_IN_SECONDS = 60 * 60 * 24 7 | # 导入RPC必备的包,以及刚才生成的两个文件(grpc,msg_pb2,msg_pb2_grpc) 8 | # 因为RPC应该长时间运行,考虑到性能,还需要用到并发的库(time,concurrent) 9 | 10 | # 在服务器端代码中需要实现proto文件中定义的服务接口(MsgService),并重写处理函数(GetMsg) 11 | # Python gRPC的服务实现是写一个子类去继承proto编译生成的userinfo_pb2_grpc.UserInfoServicer 12 | # 并且在子类中实现RPC的具体服务处理方法,同时将重写后的服务类实例化以后添加到grpc服务器中 13 | 14 | class MsgService(msg_pb2_grpc.MsgServiceServicer): 15 | # 工作函数 16 | def GetMsg(self, request, context): 17 | # 在GetMsg中设计msg.proto中定义的MsgResponse 18 | # 对收到的request的内容进行读取并根据op内容执行相关运算操作 19 | if(request.op == '+'): 20 | res=request.a+request.b 21 | if(request.op == '-'): 22 | res=request.a-request.b 23 | if(request.op == '*'): 24 | res=request.a*request.b 25 | if(request.op == '/'): 26 | res=request.a/request.b 27 | 28 | # 在服务器端打印从客户端收到的内容并打印结果,用于检验接收和计算的结果是否正确 29 | msg = "需要计算的式子为:{}{}{},结果为{}\n".format(request.a,request.op,request.b,res) 30 | print(msg) 31 | 32 | # 将结果返回给客户端 33 | return msg_pb2.MsgResponse(result = res) 34 | 35 | # 通过并发库,将服务端放到多进程里运行 36 | def serve(): 37 | # gRPC 服务器 38 | # 定义服务器并设置最大连接数,corcurrent.futures是一个并发库,类似于线程池的概念 39 | server = grpc.server(futures.ThreadPoolExecutor(max_workers=2))# 创建一个服务器server 40 | msg_pb2_grpc.add_MsgServiceServicer_to_server(MsgService(), server)# 在服务器中添加派生的接口服务(自己实现的处理函数) 41 | server.add_insecure_port('[::]:50051')# 添加监听端口 42 | print("服务器已打开,正在等待客户端连接...\n") 43 | server.start() # 启动服务器,同时start()不会阻塞,如果运行时无事发生,则循环等待 44 | try: 45 | while True: 46 | time.sleep(_ONE_DAY_IN_SECONDS) 47 | except KeyboardInterrupt: 48 | server.stop(0)# 关闭服务器 49 | if __name__ == '__main__': 50 | serve() -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_hw3/作业-3-2021.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021作业/18329015_郝裕玮_hw3/作业-3-2021.pdf -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_hw5/18329015_郝裕玮_hw5/18329015_郝裕玮_hw5.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021作业/18329015_郝裕玮_hw5/18329015_郝裕玮_hw5/18329015_郝裕玮_hw5.docx -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_hw5/18329015_郝裕玮_hw5/18329015_郝裕玮_hw5.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021作业/18329015_郝裕玮_hw5/18329015_郝裕玮_hw5/18329015_郝裕玮_hw5.pdf -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_hw5/18329015_郝裕玮_hw5/reliable-multicast-chat-master/.gitignore: -------------------------------------------------------------------------------- 1 | *.aux 2 | *.log 3 | *~ 4 | .DS_Store 5 | *.out 6 | *.pyc 7 | .idea/* 8 | .idea 9 | -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_hw5/18329015_郝裕玮_hw5/reliable-multicast-chat-master/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, Daeyun Shin, Joon Young Seo 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | * Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | * Neither the name of the project nor the 12 | names of its contributors may be used to endorse or promote products 13 | derived from this software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY 19 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_hw5/18329015_郝裕玮_hw5/reliable-multicast-chat-master/README.md: -------------------------------------------------------------------------------- 1 | #Reliable Multicast Chat 2 | 3 | ## Usage 4 | 5 | ./reliable_multicast_chat [process ID] [delay time (in seconds)] [drop rate (0<=P<1)] 6 | 7 | Execute `reliable_multicast_chat` in `./bin` folder. 8 | 9 | ## Configurations 10 | 11 | Modify `config.py` in `reliable_mulicast_chat` directory accordingly. 12 | `config['hosts']` is a list of (IP address, port). 13 | Ordering can be either 'casual' or 'total'. 14 | 15 | ## Algorithms 16 | 17 | - **Casual Ordering**: When a process receives a multicasted message, it pushes the received message to a buffer 18 | queue with a vector timestamp from the sender. And then `update_holdback_queue_casual()` takes care of updating the buffer 19 | and actually delivering the message to the process. It compares the timestamps of the buffered messages with the process's timestamp to determine which messages should be kept in the buffer or be removed and delivered to the process. 20 | 21 | - **Total Ordering**: Process 0 is always designated as the sequencer. When a process multicasts a message, other processes will hold that message in a buffer until they receive a marker message from the sequencer indicating the order of that message. When the sequencer receives a message, it increments an internal counter and assigns that number as the message's order number which will then be multicasted to all other processes. 22 | 23 | - **Reliable Multicast**: When a process unicasts a message, it stores it in the unacknowledged messages buffer and keeps it there until an `ack` message is received. We have a thread called `ack_handler` which 24 | periodically keeps track of received `ack` messages for each item in the buffer and either re-send the message or remove from the buffer depending on the message is asknowledged by the receiving process or not. The receiving process sends an `ack` message 25 | every time it receives a message, but does not actually process duplicate messages (identified with message IDs). 26 | 27 | - **Randomized Losses**: e generate a random floating point number, and if that number is 28 | smaller than the user-specified loss rate, we don't actually send the message, however, we still keep it in the unacknowledged buffer so that the `ack_handler` thread can keep re-sending the message until the receiving process acknowledges it. See above 29 | _Reliable Multicast_ for details. 30 | 31 | - **Randomized Delay**: We calculate a send_time for each outgoing message and push a tuple (send_time, message) into a queue. The `thread message_queue_handler` periodically iterates through the queue and sends out messages with current_time >= send_time. 32 | 33 | 34 | ## Requirement 35 | 36 | * Python3 37 | -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_hw5/18329015_郝裕玮_hw5/reliable-multicast-chat-master/bin/reliable_multicast_chat: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import os 3 | import sys 4 | 5 | sys.path.append(os.path.dirname(os.path.realpath(__file__)) + '/../reliable_multicast_chat/') 6 | from main import main 7 | 8 | main() 9 | -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_hw5/18329015_郝裕玮_hw5/reliable-multicast-chat-master/reliable_multicast_chat/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021作业/18329015_郝裕玮_hw5/18329015_郝裕玮_hw5/reliable-multicast-chat-master/reliable_multicast_chat/__init__.py -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_hw5/18329015_郝裕玮_hw5/reliable-multicast-chat-master/reliable_multicast_chat/chat_process.py: -------------------------------------------------------------------------------- 1 | from queue import PriorityQueue 2 | import random 3 | import socket 4 | import config 5 | import threading 6 | import sys 7 | import time 8 | import os 9 | 10 | from helpers.unicast_helper import pack_message, unpack_message, calculate_send_time 11 | from helpers.unicast_helper import stringify_vector_timestamp, parse_vector_timestamp 12 | 13 | 14 | class ChatProcess: 15 | def __init__(self, process_id, delay_time, drop_rate, num_processes): 16 | self.my_id = process_id 17 | self.delay_time = delay_time 18 | self.drop_rate = drop_rate 19 | 20 | self.message_max_size = 2048 21 | self.message_id_counter = 0 22 | self.has_received = {} 23 | self.has_acknowledged = {} 24 | self.unack_messages = [] 25 | self.holdback_queue = [] 26 | 27 | self.holdback_queue_markers = [] 28 | self.holdback_sequence_counter = 0 29 | self.sequence_counter = 0 30 | self.SEQUENCER_ID = 0 31 | 32 | self.queue = PriorityQueue() 33 | self.mutex = threading.Lock() 34 | self.my_timestamp = [0] * num_processes 35 | 36 | # Initialize the UDP socket. 37 | ip, port = config.config['hosts'][process_id] 38 | self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 39 | self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) 40 | self.sock.bind((ip, port)) 41 | self.sock.settimeout(0.01) 42 | 43 | def unicast_send(self, destination, message, msg_id=None, is_ack=False, is_order_marker=False, timestamp=None): 44 | """ Push an outgoing message to the message queue. """ 45 | if timestamp is None: 46 | timestamp = self.my_timestamp[:] 47 | 48 | is_msg_id_specified = msg_id is not None 49 | if msg_id is None: 50 | msg_id = self.message_id_counter 51 | 52 | message = pack_message([self.my_id, msg_id, is_ack, is_order_marker, stringify_vector_timestamp(timestamp), message]) 53 | 54 | if not is_ack and not is_msg_id_specified: 55 | with self.mutex: 56 | self.unack_messages.append((destination, message)) 57 | 58 | if random.random() <= self.drop_rate: 59 | return 60 | 61 | dest_ip, dest_port = config.config['hosts'][destination] 62 | send_time = calculate_send_time(self.delay_time) 63 | self.queue.put((send_time, message, dest_ip, dest_port)) 64 | 65 | def unicast_receive(self): 66 | """ Receive UDP messages from other chat processes and store them in the holdback queue. 67 | Returns True if new message was received. """ 68 | 69 | data, _ = self.sock.recvfrom(self.message_max_size) 70 | [sender, message_id, is_ack, is_order_marker, message_timestamp, message] = unpack_message(data) 71 | 72 | if is_ack: 73 | self.has_acknowledged[(sender, message_id)] = True 74 | else: 75 | # send acknowledgement to the sender 76 | self.unicast_send(int(sender), "", message_id, True) 77 | if (sender, message_id) not in self.has_received: 78 | self.has_received[(sender, message_id)] = True 79 | if config.config['ordering'] == 'casual': 80 | self.holdback_queue.append((sender, message_timestamp[:], message)) 81 | self.update_holdback_queue_casual() 82 | return True 83 | else: 84 | if is_order_marker: 85 | m_sequencer, m_sender, m_id = [int(x) for x in message.split(';')] 86 | self.holdback_queue_markers.append((m_sender, m_id, m_sequencer)) 87 | self.update_holdback_queue_total() 88 | else: 89 | if self.my_id == self.SEQUENCER_ID: 90 | marker_message = ';'.join([str(x) for x in [self.sequence_counter, sender, message_id]]) 91 | self.multicast(marker_message, is_order_marker=True) 92 | self.sequence_counter += 1 93 | 94 | self.holdback_queue.append((sender, message_id, message)) 95 | self.update_holdback_queue_total() 96 | return True 97 | return False 98 | 99 | def update_holdback_queue_casual(self): 100 | """ Compare message timestamps to ensure casual ordering. """ 101 | while True: 102 | new_holdback_queue = [] 103 | removed_messages = [] 104 | for sender, v, message in self.holdback_queue: 105 | should_remove = True 106 | for i in range(len(v)): 107 | if i == sender: 108 | if v[i] != self.my_timestamp[i] + 1: 109 | should_remove = False 110 | else: 111 | if v[i] > self.my_timestamp[i]: 112 | should_remove = False 113 | if not should_remove: 114 | new_holdback_queue.append((sender, v, message)) 115 | else: 116 | removed_messages.append((sender, v, message)) 117 | 118 | for sender, v, message in removed_messages: 119 | self.my_timestamp[sender] += 1 120 | self.deliver(sender, message) 121 | 122 | self.holdback_queue = new_holdback_queue 123 | 124 | if not removed_messages: 125 | break 126 | 127 | def update_holdback_queue_total(self): 128 | while True: 129 | # TODO: reduce marker list size 130 | new_holdback_queue = [] 131 | is_ever_delivered = False 132 | for sender, message_id, message in self.holdback_queue: 133 | is_delivered = False 134 | for m_sender, m_message_id, m_sequence in self.holdback_queue_markers: 135 | m_sequence_int = int(m_sequence) 136 | if sender == m_sender and message_id == m_message_id and self.holdback_sequence_counter == m_sequence_int: 137 | self.deliver(sender, message) 138 | is_delivered = True 139 | is_ever_delivered = True 140 | self.holdback_sequence_counter += 1 141 | break 142 | 143 | if not is_delivered: 144 | new_holdback_queue.append((sender, message_id, message)) 145 | 146 | self.holdback_queue = new_holdback_queue 147 | 148 | if not is_ever_delivered: 149 | break 150 | 151 | def multicast(self, message, is_order_marker=False): 152 | """ Unicast the message to all known clients. """ 153 | for process_id, host in enumerate(config.config['hosts']): 154 | self.unicast_send(process_id, message, is_order_marker=is_order_marker) 155 | self.message_id_counter += 1 156 | 157 | def deliver(self, sender, message): 158 | """ Do something with the received message. """ 159 | print(sender, "says: ", message) 160 | 161 | def message_queue_handler(self): 162 | """ Thread that actually sends out messages when send time <= current_time. """ 163 | while True: 164 | (send_time, message, ip, port) = self.queue.get(block=True) 165 | if send_time <= time.time(): 166 | self.sock.sendto(message, (ip, port)) 167 | else: 168 | self.queue.put((send_time, message, ip, port)) 169 | time.sleep(0.01) 170 | 171 | def ack_handler(self): 172 | """ Thread that re-sends all unacknowledged messages. """ 173 | while True: 174 | time.sleep(0.2) 175 | 176 | with self.mutex: 177 | new_unack_messages = [] 178 | for dest_id, packed_message in self.unack_messages: 179 | [_, message_id, is_ack, is_order_marker, message_timestamp, message] = unpack_message(packed_message) 180 | if (dest_id, message_id) not in self.has_acknowledged: 181 | new_unack_messages.append((dest_id, packed_message)) 182 | self.unicast_send(dest_id, message, msg_id=message_id, is_ack=is_ack, 183 | is_order_marker=is_order_marker, timestamp=message_timestamp) 184 | self.unack_messages = new_unack_messages 185 | 186 | def user_input_handler(self): 187 | """ Thread that waits for user input and multicasts to other processes. """ 188 | for line in sys.stdin: 189 | line = line[:-1] 190 | self.my_timestamp[self.my_id] += 1 191 | self.multicast(line) 192 | 193 | def incoming_message_handler(self): 194 | """ Thread that listens for incoming UDP messages """ 195 | while True: 196 | try: 197 | self.unicast_receive() 198 | except (socket.timeout, BlockingIOError) as e: 199 | pass 200 | 201 | def run(self): 202 | """ Initialize and start all threads. """ 203 | thread_routines = [ 204 | self.ack_handler, 205 | self.message_queue_handler, 206 | self.incoming_message_handler, 207 | self.user_input_handler, 208 | ] 209 | 210 | threads = [] 211 | for thread_routine in thread_routines: 212 | thread = threading.Thread(target=thread_routine) 213 | thread.daemon = True 214 | thread.start() 215 | threads.append(thread) 216 | 217 | for thread in threads: 218 | thread.join() 219 | -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_hw5/18329015_郝裕玮_hw5/reliable-multicast-chat-master/reliable_multicast_chat/config.py: -------------------------------------------------------------------------------- 1 | """ 2 | hosts is a list of (IP address, port) 3 | 4 | ordering can be either 'casual' or 'total' 5 | """ 6 | 7 | config = { 8 | 'hosts': [ 9 | ('localhost', 16406), 10 | ('localhost', 16407), 11 | ('localhost', 16408), 12 | ('localhost', 16409), 13 | ('localhost', 16410), 14 | ('localhost', 16411), 15 | ], 16 | 'ordering': 'casual', 17 | } 18 | -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_hw5/18329015_郝裕玮_hw5/reliable-multicast-chat-master/reliable_multicast_chat/helpers/unicast_helper.py: -------------------------------------------------------------------------------- 1 | import random 2 | import time 3 | 4 | 5 | def pack_message(message_list): 6 | return (','.join([str(x) for x in message_list])).encode('utf-8') 7 | 8 | 9 | def unpack_message(message): 10 | message = message.decode('utf-8') 11 | sender, message_id, is_ack, is_order_marker, vector_str, message = message.split(',', 5) 12 | 13 | sender = int(sender) 14 | message_id = int(message_id) 15 | timestamp = parse_vector_timestamp(vector_str) 16 | is_ack = is_ack in ['True', 'true', '1'] 17 | is_order_marker = is_order_marker in ['True', 'true', '1'] 18 | 19 | return [sender, message_id, is_ack, is_order_marker, timestamp, message] 20 | 21 | 22 | def parse_vector_timestamp(vector_str): 23 | return [int(x) for x in vector_str.split(';')] 24 | 25 | 26 | def stringify_vector_timestamp(vector): 27 | return ';'.join([str(x) for x in vector]) 28 | 29 | 30 | def calculate_send_time(delay_time): 31 | """ delay_time in seconds """ 32 | delay_time = random.uniform(0, 2 * delay_time) 33 | return time.time() + delay_time 34 | -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_hw5/18329015_郝裕玮_hw5/reliable-multicast-chat-master/reliable_multicast_chat/main.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import config 3 | from chat_process import ChatProcess 4 | 5 | 6 | def main(): 7 | if len(sys.argv) != 4: 8 | print('Usage: {} [process ID] [delay time] [drop rate]'.format(sys.argv[0])) 9 | exit(1) 10 | 11 | process_id = int(sys.argv[1]) 12 | delay_rate = float(sys.argv[2]) 13 | drop_rate = float(sys.argv[3]) 14 | num_processes = len(config.config['hosts']) 15 | 16 | chat_process = ChatProcess(process_id, delay_rate, drop_rate, num_processes) 17 | chat_process.run() 18 | 19 | if __name__ == '__main__': 20 | main() -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_hw5/作业-5.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021作业/18329015_郝裕玮_hw5/作业-5.pdf -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_hw6/18329015_郝裕玮_hw6/18329015_郝裕玮_hw6.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021作业/18329015_郝裕玮_hw6/18329015_郝裕玮_hw6/18329015_郝裕玮_hw6.docx -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_hw6/18329015_郝裕玮_hw6/18329015_郝裕玮_hw6.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021作业/18329015_郝裕玮_hw6/18329015_郝裕玮_hw6/18329015_郝裕玮_hw6.pdf -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_hw6/18329015_郝裕玮_hw6/proto/__pycache__/msg_pb2.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021作业/18329015_郝裕玮_hw6/18329015_郝裕玮_hw6/proto/__pycache__/msg_pb2.cpython-37.pyc -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_hw6/18329015_郝裕玮_hw6/proto/__pycache__/msg_pb2_grpc.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021作业/18329015_郝裕玮_hw6/18329015_郝裕玮_hw6/proto/__pycache__/msg_pb2_grpc.cpython-37.pyc -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_hw6/18329015_郝裕玮_hw6/proto/client.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021作业/18329015_郝裕玮_hw6/18329015_郝裕玮_hw6/proto/client.py -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_hw6/18329015_郝裕玮_hw6/proto/msg.proto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021作业/18329015_郝裕玮_hw6/18329015_郝裕玮_hw6/proto/msg.proto -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_hw6/18329015_郝裕玮_hw6/proto/msg_pb2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by the protocol buffer compiler. DO NOT EDIT! 3 | # source: msg.proto 4 | """Generated protocol buffer code.""" 5 | from google.protobuf import descriptor as _descriptor 6 | from google.protobuf import message as _message 7 | from google.protobuf import reflection as _reflection 8 | from google.protobuf import symbol_database as _symbol_database 9 | # @@protoc_insertion_point(imports) 10 | 11 | _sym_db = _symbol_database.Default() 12 | 13 | 14 | 15 | 16 | DESCRIPTOR = _descriptor.FileDescriptor( 17 | name='msg.proto', 18 | package='', 19 | syntax='proto3', 20 | serialized_options=None, 21 | create_key=_descriptor._internal_create_key, 22 | serialized_pb=b'\n\tmsg.proto\"\x1a\n\nMsgRequest\x12\x0c\n\x04text\x18\x01 \x01(\t\")\n\x0bMsgResponse\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x0e\n\x06result\x18\x02 \x01(\t23\n\nMsgService\x12%\n\x06GetMsg\x12\x0b.MsgRequest\x1a\x0c.MsgResponse\"\x00\x62\x06proto3' 23 | ) 24 | 25 | 26 | 27 | 28 | _MSGREQUEST = _descriptor.Descriptor( 29 | name='MsgRequest', 30 | full_name='MsgRequest', 31 | filename=None, 32 | file=DESCRIPTOR, 33 | containing_type=None, 34 | create_key=_descriptor._internal_create_key, 35 | fields=[ 36 | _descriptor.FieldDescriptor( 37 | name='text', full_name='MsgRequest.text', index=0, 38 | number=1, type=9, cpp_type=9, label=1, 39 | has_default_value=False, default_value=b"".decode('utf-8'), 40 | message_type=None, enum_type=None, containing_type=None, 41 | is_extension=False, extension_scope=None, 42 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 43 | ], 44 | extensions=[ 45 | ], 46 | nested_types=[], 47 | enum_types=[ 48 | ], 49 | serialized_options=None, 50 | is_extendable=False, 51 | syntax='proto3', 52 | extension_ranges=[], 53 | oneofs=[ 54 | ], 55 | serialized_start=13, 56 | serialized_end=39, 57 | ) 58 | 59 | 60 | _MSGRESPONSE = _descriptor.Descriptor( 61 | name='MsgResponse', 62 | full_name='MsgResponse', 63 | filename=None, 64 | file=DESCRIPTOR, 65 | containing_type=None, 66 | create_key=_descriptor._internal_create_key, 67 | fields=[ 68 | _descriptor.FieldDescriptor( 69 | name='id', full_name='MsgResponse.id', index=0, 70 | number=1, type=5, cpp_type=1, label=1, 71 | has_default_value=False, default_value=0, 72 | message_type=None, enum_type=None, containing_type=None, 73 | is_extension=False, extension_scope=None, 74 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 75 | _descriptor.FieldDescriptor( 76 | name='result', full_name='MsgResponse.result', index=1, 77 | number=2, type=9, cpp_type=9, label=1, 78 | has_default_value=False, default_value=b"".decode('utf-8'), 79 | message_type=None, enum_type=None, containing_type=None, 80 | is_extension=False, extension_scope=None, 81 | serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), 82 | ], 83 | extensions=[ 84 | ], 85 | nested_types=[], 86 | enum_types=[ 87 | ], 88 | serialized_options=None, 89 | is_extendable=False, 90 | syntax='proto3', 91 | extension_ranges=[], 92 | oneofs=[ 93 | ], 94 | serialized_start=41, 95 | serialized_end=82, 96 | ) 97 | 98 | DESCRIPTOR.message_types_by_name['MsgRequest'] = _MSGREQUEST 99 | DESCRIPTOR.message_types_by_name['MsgResponse'] = _MSGRESPONSE 100 | _sym_db.RegisterFileDescriptor(DESCRIPTOR) 101 | 102 | MsgRequest = _reflection.GeneratedProtocolMessageType('MsgRequest', (_message.Message,), { 103 | 'DESCRIPTOR' : _MSGREQUEST, 104 | '__module__' : 'msg_pb2' 105 | # @@protoc_insertion_point(class_scope:MsgRequest) 106 | }) 107 | _sym_db.RegisterMessage(MsgRequest) 108 | 109 | MsgResponse = _reflection.GeneratedProtocolMessageType('MsgResponse', (_message.Message,), { 110 | 'DESCRIPTOR' : _MSGRESPONSE, 111 | '__module__' : 'msg_pb2' 112 | # @@protoc_insertion_point(class_scope:MsgResponse) 113 | }) 114 | _sym_db.RegisterMessage(MsgResponse) 115 | 116 | 117 | 118 | _MSGSERVICE = _descriptor.ServiceDescriptor( 119 | name='MsgService', 120 | full_name='MsgService', 121 | file=DESCRIPTOR, 122 | index=0, 123 | serialized_options=None, 124 | create_key=_descriptor._internal_create_key, 125 | serialized_start=84, 126 | serialized_end=135, 127 | methods=[ 128 | _descriptor.MethodDescriptor( 129 | name='GetMsg', 130 | full_name='MsgService.GetMsg', 131 | index=0, 132 | containing_service=None, 133 | input_type=_MSGREQUEST, 134 | output_type=_MSGRESPONSE, 135 | serialized_options=None, 136 | create_key=_descriptor._internal_create_key, 137 | ), 138 | ]) 139 | _sym_db.RegisterServiceDescriptor(_MSGSERVICE) 140 | 141 | DESCRIPTOR.services_by_name['MsgService'] = _MSGSERVICE 142 | 143 | # @@protoc_insertion_point(module_scope) 144 | -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_hw6/18329015_郝裕玮_hw6/proto/msg_pb2_grpc.py: -------------------------------------------------------------------------------- 1 | # Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! 2 | """Client and server classes corresponding to protobuf-defined services.""" 3 | import grpc 4 | 5 | import msg_pb2 as msg__pb2 6 | 7 | 8 | class MsgServiceStub(object): 9 | """Missing associated documentation comment in .proto file.""" 10 | 11 | def __init__(self, channel): 12 | """Constructor. 13 | 14 | Args: 15 | channel: A grpc.Channel. 16 | """ 17 | self.GetMsg = channel.unary_unary( 18 | '/MsgService/GetMsg', 19 | request_serializer=msg__pb2.MsgRequest.SerializeToString, 20 | response_deserializer=msg__pb2.MsgResponse.FromString, 21 | ) 22 | 23 | 24 | class MsgServiceServicer(object): 25 | """Missing associated documentation comment in .proto file.""" 26 | 27 | def GetMsg(self, request, context): 28 | """Missing associated documentation comment in .proto file.""" 29 | context.set_code(grpc.StatusCode.UNIMPLEMENTED) 30 | context.set_details('Method not implemented!') 31 | raise NotImplementedError('Method not implemented!') 32 | 33 | 34 | def add_MsgServiceServicer_to_server(servicer, server): 35 | rpc_method_handlers = { 36 | 'GetMsg': grpc.unary_unary_rpc_method_handler( 37 | servicer.GetMsg, 38 | request_deserializer=msg__pb2.MsgRequest.FromString, 39 | response_serializer=msg__pb2.MsgResponse.SerializeToString, 40 | ), 41 | } 42 | generic_handler = grpc.method_handlers_generic_handler( 43 | 'MsgService', rpc_method_handlers) 44 | server.add_generic_rpc_handlers((generic_handler,)) 45 | 46 | 47 | # This class is part of an EXPERIMENTAL API. 48 | class MsgService(object): 49 | """Missing associated documentation comment in .proto file.""" 50 | 51 | @staticmethod 52 | def GetMsg(request, 53 | target, 54 | options=(), 55 | channel_credentials=None, 56 | call_credentials=None, 57 | insecure=False, 58 | compression=None, 59 | wait_for_ready=None, 60 | timeout=None, 61 | metadata=None): 62 | return grpc.experimental.unary_unary(request, target, '/MsgService/GetMsg', 63 | msg__pb2.MsgRequest.SerializeToString, 64 | msg__pb2.MsgResponse.FromString, 65 | options, channel_credentials, 66 | insecure, call_credentials, compression, wait_for_ready, timeout, metadata) 67 | -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_hw6/18329015_郝裕玮_hw6/proto/server1.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021作业/18329015_郝裕玮_hw6/18329015_郝裕玮_hw6/proto/server1.py -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_hw6/18329015_郝裕玮_hw6/proto/server2.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021作业/18329015_郝裕玮_hw6/18329015_郝裕玮_hw6/proto/server2.py -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_hw6/18329015_郝裕玮_hw6/proto/server3.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021作业/18329015_郝裕玮_hw6/18329015_郝裕玮_hw6/proto/server3.py -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_hw6/作业-6-一致性与复制.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021作业/18329015_郝裕玮_hw6/作业-6-一致性与复制.pdf -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_大作业/18329015_郝裕玮_计科1班.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021作业/18329015_郝裕玮_大作业/18329015_郝裕玮_计科1班.docx -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_大作业/18329015_郝裕玮_计科1班.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021作业/18329015_郝裕玮_大作业/18329015_郝裕玮_计科1班.pdf -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_大作业/test/client.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | import argparse 3 | import rpyc 4 | # argparse库:用于解析参数,并为这些参数自动生成帮助和使用信息(用于美化UI界面) 5 | # rpyc库:它是一个Python的库,用于实现RPC和分布式计算 6 | 7 | #Client类:客户端 8 | class Client(object): 9 | #在cmd中输入help会显示如下信息 10 | """ 11 | Commands Help: 12 | PUT key value —— Generate/Modify (key, value) 13 | GET key —— Query (key, value) by the key 14 | GETALL —— Get all (key, value) in the database 15 | DEL key —— Delete (key, value) by the key 16 | DELALL —— Delete all (key, value) in the database 17 | GETLOG —— Get the log 18 | """ 19 | 20 | #客户端与master节点连接 21 | def connect(self): 22 | self.conn = rpyc.connect('localhost', 21000) 23 | #获取自己独有的客户ID 24 | #client要访问Master节点的代码必须通过self.conn.root.xxx才能访问 25 | self.id = self.conn.root.get_id() 26 | return self.id 27 | 28 | #进入运行界面 29 | def run(self): 30 | try: 31 | while True: 32 | #输入指令 33 | command = input("Client %d >> " %self.id) 34 | #指令为help则输出指南 35 | if command == 'help': 36 | print(self.__doc__) 37 | #反之则调用Master节点中对应的功能函数 38 | else: 39 | msg = self.conn.root.function(self.id, command) 40 | #打印结果信息 41 | if msg != None: 42 | print(msg) 43 | except KeyboardInterrupt: 44 | pass 45 | 46 | 47 | #主程序 48 | if __name__ == '__main__': 49 | users = {} #初始用户列表为空 50 | #打开文件读取 51 | with open('user.txt') as file: 52 | for i in file.readlines(): 53 | #每一行是用户名+空格+密码,用split函数将其分开 54 | #users[i[0]] = i[1]代表建立字典对应值,即users[用户名]=密码 55 | i = i.split() 56 | users[i[0]] = i[1] 57 | 58 | #用户登录 59 | username = input('Please input your username:') 60 | password = input('Please input your password:') 61 | #检测用户名和密码是否匹配 62 | if username in users.keys() and users[username] == password: 63 | client = Client() 64 | client_id = client.connect() 65 | 66 | if client_id == None: 67 | print('Connection Failed.') 68 | else: 69 | print('\nWelcome to Distributed Key-Value System!\n') 70 | print('Your client ID is %d\n' %client_id) 71 | print("Enter \"help\" for the list of commands:\n") 72 | client.run() 73 | else: 74 | print('Your username or password has something wrong.Please try again!') 75 | -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_大作业/test/database.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021作业/18329015_郝裕玮_大作业/test/database.sqlite -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_大作业/test/middle.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | import argparse 3 | import rpyc 4 | from rpyc.utils.server import ThreadedServer 5 | # argparse库:用于解析参数,并为这些参数自动生成帮助和使用信息(用于美化UI界面) 6 | # rpyc库:它是一个Python的库,用于实现RPC和分布式计算 7 | 8 | #Middle类:分布式系统中间件 9 | class Middle(rpyc.Service): 10 | #当客户端到服务器的连接建立时,on_connect函数会被执行 11 | def on_connect(self, conn): 12 | pass 13 | 14 | #当客户端到服务器的连接断开时,on_disconnect函数会被执行 15 | def on_disconnect(self, conn): 16 | #依次断开客户端和服务器的连接 17 | for temp in clients: 18 | temp.close() 19 | 20 | #为当前客户分配ID 21 | def exposed_get_id(self): 22 | #遍历client_ids表,寻找尚未分配的id 23 | for i in range(len(client_ids)): 24 | #若client_ids[i]尚未分配则设置其为True(已使用)并返回序号i 25 | if client_ids[i] == False: 26 | client_ids[i] = True 27 | return i 28 | return None 29 | 30 | #执行各种command 31 | def exposed_function(self, client_id, clause): 32 | clause = clause.strip().split() 33 | #将command根据空格进行分割 34 | #strip()可消去字符串前后的空格(不包括中间) 35 | #split()将字符串根据空格进行分割 36 | lens = len(clause) 37 | 38 | WRONG_MSG = 'Wrong command. Enter help if necessary.' 39 | if lens < 1: 40 | return WRONG_MSG 41 | 42 | #将指令的第一个单词全部转为小写,便于后续判定 43 | #易知指令的第一个单词小写化后只可能是:put,get,getall,del,delall,getlog 44 | command = clause[0].lower() 45 | 46 | #开始进行条件判断 47 | #对于PUT key value 48 | if command == 'put': 49 | if lens == 3: 50 | key = clause[1] 51 | value = clause[2] 52 | #client要访问服务器的代码必须通过self.conn.root.xxx才能访问 53 | clients[client_id].root.Put(key, value) 54 | #将本次操作PUT key value写到对应客户的日志中 55 | clients[client_id].root.Write_Log('PUT ('+str(key)+','+str(value)+')') 56 | else: 57 | return WRONG_MSG 58 | 59 | #对于GET key 60 | if command == 'get': 61 | if lens == 2: 62 | key = clause[1] 63 | #client要访问服务器的代码必须通过self.conn.root.xxx才能访问 64 | result = clients[client_id].root.Get(key) 65 | #将本次操作GET key写到对应客户的日志中 66 | clients[client_id].root.Write_Log('GET '+str(key)) 67 | else: 68 | return WRONG_MSG 69 | 70 | if result == None: 71 | return 'Key %s not found.' %key 72 | else: 73 | return result 74 | 75 | #对于GETALL 76 | if command == 'getall': 77 | if lens == 1: 78 | #client要访问服务器的代码必须通过self.conn.root.xxx才能访问 79 | #将本次操作GETALL写到对应客户的日志中 80 | clients[client_id].root.Write_Log('GETALL') 81 | return clients[client_id].root.Get_All() 82 | else: 83 | return WRONG_MSG 84 | 85 | #对于DEL key 86 | if command == 'del': 87 | if lens == 2: 88 | key = clause[1] 89 | #client要访问服务器的代码必须通过self.conn.root.xxx才能访问 90 | clients[client_id].root.Delete(key) 91 | #将本次操作DEL key写到对应客户的日志中 92 | clients[client_id].root.Write_Log('DEL '+str(key)) 93 | else: 94 | return WRONG_MSG 95 | 96 | #对于DELALL 97 | if command == 'delall': 98 | if lens == 1: 99 | #client要访问服务器的代码必须通过self.conn.root.xxx才能访问 100 | #将本次操作GETALL写到对应客户的日志中 101 | clients[client_id].root.Write_Log('DELALL') 102 | return clients[client_id].root.Delete_All() 103 | else: 104 | return WRONG_MSG 105 | 106 | #对于GETLOG 107 | if command == 'getlog': 108 | if lens == 1: 109 | #client要访问服务器的代码必须通过self.conn.root.xxx才能访问 110 | return clients[client_id].root.Get_Log() 111 | else: 112 | return WRONG_MSG 113 | 114 | 115 | #主程序 116 | if __name__ == '__main__': 117 | #(1)创建ArgumentParser()对象 118 | #(2)调用add_argument()方法添加参数 119 | #(3)使用parse_args()解析添加的参数 120 | parser = argparse.ArgumentParser() 121 | parser.add_argument('--p', type=int, default=1) 122 | args = parser.parse_args() 123 | 124 | #建立一个bool数组,初始化为args.p个False变量,表示这些id都未被使用 125 | client_ids = [False] * args.p 126 | 127 | #设置中间件的监听端口号用于和不同的服务器节点相连接 128 | clients = [rpyc.connect('localhost', 20000+i) for i in range(args.p)] 129 | #设置中间件与客户端连接的端口号 130 | middle = ThreadedServer(Middle, port=21000) 131 | print("Middleware is running...\n") 132 | middle.start() 133 | -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_大作业/test/server.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | import argparse 3 | import rpyc 4 | from rpyc.utils.server import ThreadedServer 5 | from multiprocessing import Process 6 | from sqlitedict import SqliteDict 7 | # argparse库:用于解析参数,并为这些参数自动生成帮助和使用信息(用于美化UI界面) 8 | # rpyc库:它是一个Python的库,用于实现RPC和分布式计算 9 | # multiprocessing库:用于编写多线程/多进程程序 10 | # sqlitedict库:用于将字典信息存入数据库中,且支持多线程访问 11 | 12 | #用于记录当前进程下的每步操作(一个客户对应一个进程) 13 | log=[] 14 | 15 | #Server类:服务器 16 | class Server(rpyc.Service): 17 | #当客户端到服务器的连接建立时,on_connect函数会被执行 18 | def on_connect(self, conn): 19 | #连接建立时,创建一个字典数据库用于存储键值 20 | #'./database.sqlite'代表数据库文件存储路径和文件名 21 | #autocommit=True代表会对每次对数据库操作的结果自动提交 22 | self.database = SqliteDict('./database.sqlite', autocommit=True) 23 | 24 | #当客户端到服务器的连接断开时,on_disconnect函数会被执行 25 | def on_disconnect(self, conn): 26 | #pass代表不进行任何操作 27 | pass 28 | 29 | #注意,Server类中"exposed_"开头的函数才能被客户端调用 30 | #调用时需将对应函数的exposed_删去再调用 31 | #生成/修改键值对(key,value) 32 | def exposed_Put(self, key, value): 33 | self.database[key] = value 34 | 35 | #查询键值对(key,value) 36 | def exposed_Get(self, key): 37 | #通过key来查询对应的value 38 | if key not in self.database: 39 | return None 40 | else: 41 | return self.database[key] 42 | 43 | #删除键值对(key,value) 44 | def exposed_Delete(self, key): 45 | if key not in self.database: 46 | #return 47 | return None 48 | else: 49 | #根据键值k删除键值对(key,value) 50 | del self.database[key] 51 | 52 | #获取数据库中所有键值对(key,value) 53 | def exposed_Get_All(self): 54 | res = [(key, self.database[key]) for key in self.database] 55 | #对键值对进行字典序排序(根据key值排序) 56 | res.sort() 57 | return res 58 | 59 | #删除数据库中所有键值对(key,value) 60 | def exposed_Delete_All(self): 61 | all_keys = [key for key in self.database] 62 | for key in all_keys: 63 | del self.database[key] 64 | 65 | #将操作记录写入日志 66 | def exposed_Write_Log(self,msg): 67 | log.append(msg) 68 | 69 | #展示日志 70 | def exposed_Get_Log(self): 71 | return log 72 | 73 | 74 | #设置服务器监听端口号并运行服务器 75 | def run(id): 76 | port1 = id + 20000 77 | server = ThreadedServer(Server, port=port1) 78 | try: 79 | #运行服务器 80 | server.start() 81 | except KeyboardInterrupt: 82 | server.close() 83 | 84 | #主程序 85 | if __name__ == '__main__': 86 | #(1)创建ArgumentParser()对象 87 | #(2)调用add_argument()方法添加参数 88 | #(3)使用parse_args()解析添加的参数 89 | parser = argparse.ArgumentParser() 90 | parser.add_argument('--p', type=int, default=1) 91 | args = parser.parse_args() 92 | 93 | #限制服务器在同一时间段内最多只能接受10个客户端的连接和请求 94 | if args.p > 10: 95 | raise Exception("The max number of clients is 10.") 96 | 97 | #创建args.p个进程 98 | processes = [Process(target=run,args=(i,)) for i in range(args.p)] 99 | print("Server is running and it can connect with %d clients at the same time." %args.p) 100 | 101 | #启动args.p个进程,并用join函数进行堵塞 102 | #join函数:在进程中可以阻塞主进程的执行,直到等待子线程全部完成之后,再继续运行主线程后面的代码 103 | for i in range(args.p): 104 | processes[i].start() 105 | for i in range(args.p): 106 | processes[i].join() 107 | 108 | -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_大作业/test/user.txt: -------------------------------------------------------------------------------- 1 | hyw 123 2 | shao 123 3 | xxy 123 -------------------------------------------------------------------------------- /2021作业/18329015_郝裕玮_大作业/功能测试.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021作业/18329015_郝裕玮_大作业/功能测试.mp4 -------------------------------------------------------------------------------- /2021作业/分布式系统作业模板.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/2021作业/分布式系统作业模板.docx -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Distributed-Systems 2 | ## 2021中山大学分布式系统 3 | 授课教师:吴维刚&陈鹏飞
4 | 仅供参考,杜绝抄袭!
5 | 如果对你有用的话,麻烦点个star~ 6 | -------------------------------------------------------------------------------- /教材/分布式系统原理与范型 第二版.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ConstHall/Distributed-Systems/63240f30abcc1706ce1f28585bfa4a644492f8bd/教材/分布式系统原理与范型 第二版.pdf --------------------------------------------------------------------------------