2023. 4. 16. 03:47ใComputerScience/FullStackProgramming
socketserver์ ๊ธฐ๋ฐ์ผ๋ก ํ ๋น๋๊ธฐ์ 1:N programming
- [์ ๊ทผ1] Socket API ๊ธฐ๋ฐ ๊ฐ๋ฐ
- Socket API๋ ๋๋ถ๋ถ์ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์์ ์ ์ฌํจ
- Socket API๋ง์ผ๋ก 1:N ์๋ฒ๋ฅผ ๊ตฌํํ๋ ๊ฒ๋ ๋น์ฐํ ๊ฐ๋ฅํจ
- 40๋ ์ ํต์ ์์กฐ ๋ง์ง ํ๋ก๊ทธ๋๋ฐ
- [์ ๊ทผ2] ์ธ์ด๋ณ ์ฐจ๋ณํ ๋ Socket ๊ธฐ๋ฅ์ผ๋ก ๊ฐ๋ฐ
- ์ต์ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๋ ๋ณด๋ค ํฅ์๋ Socket ๊ธฐ๋ฅ์ ์ ๊ณตํจ
- ์ต์ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์ Socket ๊ธฐ๋ฅ์ผ๋ก ๋น ๋ฅธ ๊ฐ๋ฐ๊ณผ ์์ ์ ์ธ ์ฑ๋ฅ ์ ๊ณต์ด ์ฉ์ดํจ
- ์ด๊ฑด ์ธ์ด์ ๋ฐ๋ผ ์์ ์๋ ์๊ณ , ์์ ์๋ ์๋ค. ex) cpp ์ด๋ฐ๊ฑฐ ๋ชปํ ์ ์๋ค.
- [๋ณธ ๊ฐ์์ ์์ ] Python์ ๋ํ [์ ๊ทผ2]๋ก ๊ตฌํ
- socketserver๋ฅผ ํตํด ์ฝ๊ฒ Socket ์๋ฒ ๊ฐ๋ฐ์ด ๊ฐ๋ฅ
- Multi-threading/process ๊ธฐ๋ฅ์ ํตํด ์ฝ๊ฒ ๋น๋๊ธฐ์ Socket ์๋ฒ ๊ฐ๋ฐ์ด ๊ฐ๋ฅ
socketserver ๊ธฐ๋ฐ TCP Echo Server ๊ฐ๋ฐ
Python์ socketserver๋?
- ์ด๋ฏธ ์๋ฒ class๊ฐ ์กด์ฌํ๋ค!
- Socket ๊ธฐ๋ฐ ๋คํธ์ํฌ ์๋ฒ ๊ฐ๋ฐ์ ์ง์ํ๋ Python ๋ชจ๋ -> ์ฌ๋งํ๋ฉด ์์์ ๋์๊ฐ๊ฒ ํจ
- 4๊ฐ์ง ์ ํ์ ์๋ฒ ํด๋์ค๋ฅผ ์ ๊ณต
class socketserver.TCPServer(server_address, RequestHandlerClass, bind_and_activate=True)
optional : IP, Port number
์ด๋ป๊ฒ ๊ฐ๋ฐ์๋ค์ด ํธํ๊ฒ ์งค ์ ์์๊น?
์๋ฒ ํ๋ก๊ทธ๋จ์ด ํด์ผํ ์ผ์ ๊ฐ์ฒด๋ฅผ ๋ง๋ ๋ค
์ด๋ค ๋ฐ์ดํฐ๋ , ํ๋ก๊ทธ๋จ์ด๋ ์๋ฒ๊ฐ ํ ์ผ๋ฐ์ ์ธ ์ผ
-> server ๊ฐ์ฒด๋ก ๋์ (๊ฐ์ฅ ์ต์ํ์ ์ ๋ณด)
๊ฐ๋ฐ์๊ฐ ๊ด์ฌ์๋ ๊ฒ : ํน์ ๊ฐ, ์ ๋ณด, ๋ช
๋ น์ ์ฒ๋ฆฌํ๋ ๊ฒ
ํต์ requestHandler ์ ๊ตฌํํ๋ค. (custom)
๋ฐ์์ ์ฒ๋ฆฌํด์ผ ํ ๋ก์ง์ ํธ๋ค๋ฌ์ ๋ฃ์ด ๋๋ค.
๊ทธ๋ผ ์๋ฒํํ
, ๋๊ฐ ๋ฐ์ผ๋ฉด ํธ๋ค๋ฌ์๊ฒ ๋ฃ์ด์ค!
socketserver.TCPServer ๊ธฐ๋ฐ์ TCP ์๋ฒ ๋ง๋๋ ์ ์ฐจ
1. You must create a request handler class by subclassing the BaseRequestHandler class and overriding its handle() method;
- this method will process incoming requests. -> ๋ฆฌํ์คํธ ์์ฒญ๋ค์ ์ฒ๋ฆฌํ๋ ๋ฉ์๋
- ์ด๋ฏธ ๋ฒ ์ด์ค ๋ฆฌํ์คํธ ํธ๋ค๋ฌ์ ํ
ํ๋ฆฟ์ด ์๋ค.
- ์ฐ๋ฆฌ๋ handle (๋ฏธ๋๋ฉ) ๋ฉ์๋์๋ง ์์ ๋ ๊ฒ์ด๋ค.
2. You must instantiate one of the server classes, passing it the server’s address and the request handler class.
- It is recommended to use the server in a with statement.
3. Call the handle_request() or serve_forever() method of the server object to process one or many requests.
- ์ฐ๋ฆฌ๊ฐ ์คํํ๋ฉด, ๋ด๋ถ์ ์ผ๋ก ์์ํ ์๋ฒ๋ฅผ ์ด๋ ค๋๋ค.
4. Call server_close()to close the socket (unless you used a with statement).
[ ์ฅ์ ]
- ์ด์ ํ๋์ ํด๋ผ์ด์ธํธ ์๋ต ๋ฟ๋ง ์๋๋ผ, ์ฌ๋ฌ ํด๋ผ์ด์ธํธ์ ์๋ต์ ๋ฐ์ ์ ์๋ค.
- 1:1 -> import socket
- 1:N -> import socketserver
- socket, bind ๋ฑ์ ํจ์๊ฐ ๋ชจ๋ ์ฌ๋ผ์ง
- handle() ํจ์ ๋ด๋ถ์, ํธ๋ค๋ฌ ๋์์ ๋ฃ์ด์ฃผ๋ฉด ๋
[ ๋จ์ ]
- ๋์ ์ง์ ๊ฐ๋ฅํ client๋ 1๊ฐ ๋ฟ์ด๋ค.
- ๋ค๋ฅธ ํด๋ผ์ด์ธํธ๋ค์ ์๋น์ค ์ค์ธ ํด๋ผ์ด์ธํธ ์ข ๋ฃ๊น์ง ๊ธฐ๋ค๋ ค์ผ ํ๋ค.
- ์ฆ, ๋๊ธฐ์์ผ๋ก ๋์ํ๋ค. (๋น๋๊ธฐ ์ฒ๋ฆฌ X)
socketserver.TCPServer ๊ธฐ๋ฐ Echo-Server ๋ฌธ์ ์
- Each request must be completed before the next request can be started.
- This isn’t suitable if each request takes a long time to complete, because it requires a lot of computation, or because it returns a lot of data which the client is slow to process.
- The solution is to create a separate process or thread to handle each request;
the ForkingMixIn and ThreadingMixIn mix-in classes can be used to support asynchronous behaviour.
-> fork: ๋ฉํฐ ํ๋ก์ธ์ค, threading: ๋ฉํฐ ์ค๋ ๋
๋น๋๊ธฐ ์ฒ๋ฆฌ
๋๊ธฐ์ ๋์๊ณผ ๋น๋๊ธฐ์ ๋์์ ๋ฌด์์ธ๊ฐ?
- ๋๊ธฐ์ ์ฒ๋ฆฌ
- ์งํ์ค์ธ ์์ ์ด ์์ผ๋ฉด, ๋ค์ ์์ ์ ํ์ฌ ์งํ ์์ ์ข ๋ฃ ํ ์ฒ๋ฆฌ
- ํต์ blocking ์ฒ๋ฆฌ๋ผ๊ณ ํจ
- ํ์ฌ ์คํ ๋ง๊ณ ๋ ๋ค ์ ๋ฐ์์ฃผ๊ฒ ๋ค - blocking
- ๋น๋๊ธฐ์ ์ฒ๋ฆฌ
- ์งํ์ค์ธ ์์ ์ด ์์ด๋, ๋ค์ ์์ ์ด ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ๋ฐ๋ก ์คํ
- ํต์ non-blocking ์ฒ๋ฆฌํ๊ณ ํจ
- ํด๋ผ์ด์ธํธ ์ ์ฅ, ์๋ฒํํ ๋ฐ์ดํฐ ์์ฒญ ๋ณด๋ด๋๊ณ , ๋ณธ์ธ์ ๋จ์ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ํ๋ ๋ฑ ๋น๋๊ธฐ์ ์ธ ๋์
- ์๋ฒ ์ ์ฅ, ์ฌ๋ฌ ๊ฐ์ ํด๋ผ์ด์ธํธ๋ฅผ ๋์์ ๋ฐ์์ฃผ๋ ๊ฒ
Multi-Thread/Process๋ ๋ฌด์์ธ๊ฐ?
- “์ผ๊พผ์ด ๋๋ ํ๋ก๊ทธ๋จ ๊ฐ์๋ฅผ ์ฆ๊ฐ"
- Multi-Process์ Multi-Thread๊ฐ ์ผ๋ฐ์ ์
1) Multi-Process
๋
๋ฆฝ์ ์ธ ํ๋ก๊ทธ๋จ ์คํ
์ฃผ๋ก fork()๋ก ์คํ
์คํ ํ์ผ์ ์คํํ ํ
์ปดํจํฐ ๋ฉ๋ชจ๋ฆฌ ์์ ์ฌ๋ผ์จ ์ํฉ
ํ๋ ๋ ์คํํ๋ฉด -> ๋ณ๋์ ์ฝ๋๊ฐ ๋ฉ๋ชจ๋ฆฌ์ ๋
๋ฆฝ์ ์ผ๋ก ์ฌ๋ผ๊ฐ (multi process)
์ฆ, ๋ ๊ฐ ์ด์์ ์คํ ํ์ผ์ ๋์์ ์คํ์ํจ ๊ฒ
2) Multi-Thread (๋ณธ ๊ฐ์ ์ฌ๋ก)
๋ฐ์ดํฐ๋ฅผ ๊ณต์ ํ๋ ์ผ๊พผ
์ถ๊ฐ ์ผ๊พผ์ Thread ๋ผ๊ณ ์นญํจ
Process ๋ณด๋ค ์์ ์๊ตฌ ์ ์
ํ๋ก์ธ์ค ๊ฐ ๊ณต์ ํ๊ฒ ๋๋ฉด, ๋ ๊ฐ๋ณ๊ฒ ์ฒ๋ฆฌํ ์ ์์์?
๋
๋ฆฝ์ ์ผ๋ก ์ค๋ ๋๋ฅผ ๋์๋ดค์, ๋๋ฌด ๋ฌด๊ฑฐ์
๊ณต์ ํ ๊ฑด ๊ณต์ ํ๊ณ , ๊ทธ ์์์ ์ผ๊พผ๋ค์ (๊ธฐ๋ฅ, ์์
์) ๋ถ๋ดํด์ ์ฒ๋ฆฌํ์ -> ๋ฉํฐ์ค๋ ๋
ํ๋ก๊ทธ๋จ์ด ํ๋๋ง ์คํ๋๋ค.
๊ณต์ ํ ๋ฐ์ดํฐ๋ ๊ณต์ ํ๋ฉฐ, ํจ์ ํ๋, ํด๋์ค ํ๋ ๊ฐ๊ฐ์ ์ฌ๋ฌ ๊ฐ ๋์ด๋ค
์คํ ํ์ผ ํ๋ ์คํ์์ผฐ์ผ๋, ๊ทธ ์์์ ํจ์ ์ฌ๋ฌ ๊ฐ์ ๋น๋๊ธฐ ์์
์ ํ๊ฑฐ๋ ๋ฑ๋ฑ
[ ์ฅ์ ]
- ์์ ์๊ตฌ์ฌํญ์ด ์๋ค
- ์ค๋ ๋๋ฅผ ์ฌ๋ฌ ๊ฐ ๋ง๋ค๋ฉด, ์ด์์ฒด์ ๊ฐ ์ฝ์ด๋ง๋ค ๋๋ ์ค๋ค -> ํ๋ก๊ทธ๋จ ์ฑ๋ฅ ํฅ์ ok
๋น๋๊ธฐ์ TCP socketserver ๊ฐ๋ฐ
ํ์ด์ฌ, ๋น๋๊ธฐ๋ก ๋์ํ๋ 1:N ์๋ฒ -> ์์ฃผ ์ฝ๊ฒ ๋ฉํฐ์ค๋ ๋๋ฅผ ๊ตฌํ
[๋จ๊ณ1] socketserver์ multi-thread ๋ฒ์ ์์ฑ
- Forking and threading versions of each type of server can be created using these mix-in classes.
- ์๋ฌด ๋์๋ ์ถ๊ฐํ๊ณ ์ถ์ง ์๋ค๋ฉด -> ๊ทธ ์ธ์๋ ํ ๊ฒ ์๋ค.
- The mix-in class comes first, since it overrides a method defined in socketserver.
Setting the various attributes also changes the behavior of the underlying server mechanism.
- Threadingmixin ๋จผ์ , ์ดํ tcp server ์คํ ๋จ
- ๋ ๊ฐ์ ํด๋์ค๋ก๋ถํฐ, threaded TCP ์๋ฒ๋ฅผ ๋ง๋ค์ด๋ธ ๊ฒ
- Threadingmixin - ๊ธฐ์กด tcp ์๋ฒ์ ๋ฉํฐ ์ค๋ ๋ฉ์ ๊ตฌํํ๊ธฐ์ํ ์ด๊ฑธ ์ถ๊ฐํ๋ฉด, ๊ทธ๋ฅ ๋ฉํฐ ์ค๋ ๋๊ฐ ๋จ
- Threadingmixin class
-> ๋ณธ์ธ ์ค์ค๋ก๋ถํฐ ๊ฐ์ฒด๋ฅผ ๋ง๋ค์์ ๋ ๋ณ ์๋ฏธ๊ฐ ์๋ค
๋ค๋ฅธ ํด๋์ค์ ํฌํจ์ด ๋์์ ๋ ์ ์๋ฏธ - ex) ์ด ํด๋์ค๋ก๋ถํฐ ๋ง๋ค์ด์ง๋ ๊ฐ์ฒด์ ์๋ ๋ช ๊ฐ์ด๋?
์ผ์ข ์ ํด ์ฒ๋ผ ์ฐ์ด๋ ํด๋์ค๋ค -> mixIn์ด๋ผ๊ณ ๋ถ๋ฅธ๋ค
ํ์ํ ๋ ์ด๋ฐ ์ ๋ค์ ๋ณธ์ธ ํด๋์ค์ ์ง์ด๋ฃ๋๋ค. ex) objective-C
[๋จ๊ณ2] socketserver์ Request Handler๋ฅผ ์์
- To implement a service, you must derive a class from BaseRequestHandler and redefine its handle() method.
ํธ๋ค๋ฌ ๋ด๋ถ - echo ๋๋ ค๋ณด๋ด๋ ๋์ ๋ฟ
์ด์ ๋ ์ด๊ฒ ๋ฉํฐ์ค๋ ๋ ์ฒ๋ฆฌ๊ฐ ๋์ด, ์ค๋ ๋ 1, 2, 3 ๋ก ๋์ด๋ค - You can then run various versions of the service by combining one of the server classes with your request handler class.
- The request handler class must be different for datagram or stream services. This can be hidden by using the handler subclasses StreamRequestHandler or DatagramRequestHandler.
- ์ด๋ ์ค๋ ๋๊ฐ ์ฒ๋ฆฌํ๊ณ ์๋์ง ๋ณด์ฌ์ฃผ๊ณ ์ cur_thread.name์ ๋์ ์ง๋ง, ์ด๊ฑฐ ์ง์ฐ๋ฉด ์์ 1:1์ด๋ ์ฝ๋ ๋๊ฐ๋ค
๊ธฐ๋ณธ์ ์ผ๋ก๋, ๋ฉํฐ ์ค๋ ๋ํ ํ ๋, ํธ๋ค๋ฌ ๋ด๋ถ์ ๋ ํด์ค ์์ ์์
[๋จ๊ณ3] Main Thread ์ค์ ๋ฐ ์คํ
- When inheriting from ThreadingMixIn for threaded connection behavior, you should explicitly declare how you want your threads to behave on an abrupt shutdown.
- ๋ฉํฐ ์ค๋ ๋์ ์ฒ ํ
์ค๋ ๋๋ฅผ ๋์ฐ๊ณ ๋๋ฉด - ์ด์์ฒด์ ๋ ๊ฐ๊ฐ ๋ ๋ฆฝ์ ์ผ๋ก ๋ฐ๋ผ๋ณธ๋ค.
๊ฐ์ด ์ฃฝ์๊ฑฐ๋? ๋ชจ๋ ๋ ๋ฆฝ์ ์ผ๋ก ์ฃฝ์ ๊ฒ์ด๋?
1) ํ๋ก๊ทธ๋จ์ด ์ฃฝ์ผ๋ฉฐ, ํ์ฌ ๋์ด ์ค๋ ๋๋ฅผ ๋ค ์ข ๋ฃ์ํค๊ณ ์ถ์ ๋
-> ํ๋ก๊ทธ๋จ์ ์ข ๋ฃ๋ ๋ง์ง๋ง ์ค๋ ๋๊ฐ ์ข ๋ฃ๋ ๋ ๊น์ง ๊ธฐ๋ค๋ฆฌ๋์ง?
or 2) ํ๋ก๊ทธ๋จ์ ์ฃฝ๊ณ , ์ค๋ ๋๋ค์ ๋ ๋ฆฝ์ ์ผ๋ก ์ฃฝ๋๋ค - The ThreadingMixIn class defines an attribute daemon_threads, which indicates whether or not the server should wait for thread termination.
daemon ๊ฐ์ผ๋ก ๊ธฐ๋ค๋ฆด๊ฑฐ๋ ๋ง๊ฑฐ๋๋ฅผ ๊ฒฐ์ ํ ์ ์๋ค. - You should set the flag explicitly if you would like threads to behave autonomously;
the default is False, meaning that Python will not exit until all threads created by ThreadingMixIn have exited. - ์๋ฒ๊ฐ ์ฃฝ์ ๋ ํ ์ผ์ด ๋ง๋ค. (DB ๋ซ๊ณ ๋ฑ๋ฑ) -> ์์๊ฒ ์ฃฝ๋ ๊ฒ์ด ์ข๋ค.
- threading.Thread(target=server.serve_forever)
- This constructor should always be called with keyword arguments.
- target is the callable object to be invoked by the run() method.
- ์๋ฒ๋ฅผ ๋ฉํฐ์ค๋ ๋๋ก ๋์ -> server.serve_forever ์๋ก๋ถํฐ ํธ๋ค๋ฌ๊ฐ ๋จ๋ ์จ๋๊ฐ ๋จ
- server_thread.start()
- Start the thread’s activity.
- ์์ ์ ๋๊ณ , ๊ทธ๋ฅ ๋ฉ์ธ ์ค๋ ๋ ์คํ
- threading.active_count()
- Return the number of Thread objects currently alive.
- ์ด์์๋ ์ค๋ ๋์ ์ ๊ถ๊ธํ๋ค๋ฉด
- server_thread.run()
- Method representing the thread’s activity.
- You may override this method in a subclass. The standard run() method invokes the callable object passed to the object’s constructor as the target argument.
- ๋ฉ์ธ ๋์ฐ๋ฉด์ ๊ฐ๋ฐ์๊ฐ ๋ญ๊ฐ ํ๊ณ ์ถ๋ค? -> ๋ฐ ๋ฉ์๋๋ฅผ ์ค๋ฒ๋ผ์ด๋
- Threadingmixin์ผ๋ก ๋ฉํฐ ์ค๋ ๋ฉ์ ๊ตฌ๋ถํ ์ ์๋ค!
Socket Programming (N:M)
๋น๋๊ธฐ์ TCP Chatting ์๋น์ค ๊ฐ๋ฐ
- ๋น๋๊ธฐ์ TCP socketserver๋ฅผ ๊ธฐ๋ฐ์ผ๋ก 1:N ์ฑํ ์ ์ํ ๊ฐ๋จํ ํํ์ server์ client๋ฅผ ๊ฐ๋ฐ
- ํด๋ผ์ด์ธํธ ํ๋๊ฐ ๋ณด๋ธ ์ ๋ณด๋ฅผ ๋ค๋ฅธ ์ ๋คํํ ๋ ๋ฟ๋ฆผ -> ๋ฉํฐ ์บ์คํธ -> ์ดํ๋ฆฌ์ผ์ด์ ๋ก์ง์ด ํ์ํจ
- Server ๋ณ๊ฒฝ ๋ด์ฉ
- (์์ค์ฝ๋์ {CHAT} ๋ถ๋ถ) -> CHAT์ด ๋ฐ๋ ๋ถ๋ถ
- ๋ชจ๋ client์ socket ์ฐ๊ฒฐ ์ ๋ณด๋ฅผ ์ ์ฅํด๋๋ค (๋ฑ๋ก ๋ฐ ์ญ์ )
N๊ฐ์ ์ ์ ๋ฅผ ํ๋์ ์ฑํ ๋ฐฉ์ผ๋ก ๋ฃ๋ ๊ฒ - ํน์ client๊ฐ ์ ์กํ ๋ฉ์์ง๋ฅผ ๋ชจ๋ client๋ค์ ์ ๋ฌํจ
- ์ฌ๋ฌ ๊ฐ์ ํด๋ผ์ด์ธํธ๋ฅผ ๋น๋๊ธฐ๋ก ์ฒ๋ฆฌํ๊ธฐ ์ํด์
๊ธฐ์กด ํด๋ผ์ด์ธํธ๋ ๋ณด๋ด๊ณ , ๊ธฐ๋ค๋ ธ๋ค.
new ํด๋ผ์ด์ธํธ -> ๋ณธ์ธ์ด ๋ณด๋ด๋ฉด์, ์๋ฒ๋ฅผ ํตํด ๋ฉ์ธ์ง๋ฅผ ๋ฐ์ ์ ์๋๋ก
์ฆ, ์๋ฐฉํฅ ์ฑํ ์ด ๊ฐ๋ฅํ๋๋ก, ํด๋ผ์ด์ธํธ๋ฅผ ๋ฉํฐ์ค๋ ๋ํ ํ ๊ฒ
- Client ๋ณ๊ฒฝ ๋ด์ฉ
- Thread๋ฅผ ์ฌ์ฉํ์ฌ, ์ ์ก๊ณผ ์์ ์ ๋น๋๊ธฐ์ ์ผ๋ก ๋ถ๋ฆฌํจ
- ์์ Thread๋ฅผ ํตํด์, ์๋ฒ๋ก ๋ถํฐ์ ์ ์ก์ ํญ์ ์ค๋นํจ
- ํด๋ผ์ด์ธํธ ๊ตฌํ
์์ ์ ์ค๋ ๋ํ -> ๋ฐฑ๊ทธ๋ผ์ด๋๋ก ๋๋ฆผ
์ฌ์ฉ์์์ ๋ํ -> ๋๊ธฐ ๋ฐฉ์์ผ๋ก ๊ตฌํ
- Client
- ๋ค์๋ ํ๋ผ๋ฏธํฐ ๊ธฐ๋ฒ
- ํฌ์ง์ ๋ํ๋ค = ์ผ๋ฐ์ ์ผ๋ก ๊ฑ ๋๋ ค๋ฃ๋ ํธ์ถ
- ๋ณ์๋ค์ ์ด๋ฆ์ ๋ค์๊ณผ ๊ฐ์ด ์ง์ ํ ์ ์๋ค
- ํธ์ถ์ ํ ๋, ํฌ์ง์ ๋ํ์ง ์๊ณ , ์ ๋ ฅ ํ๋ผ๋ฏธํฐ์ ์ด๋ฆ์ ์ฃผ๋ ๊ฒ
- ์์ ์์ด ๋์ํ ์ ์๋ค. ์์ ๋ค์ง์ด์ง ์ฑ ์ ๋ฌํด๋ ๊ด์ฐฎ๋ค.
- ์ ์ด๋ฐ ๊ธฐ๋ฒ์ ์ฌ์ฉ?
- ์ ๋ ฅ ํ๋ผ๋ฏธํฐ๊ฐ 10๊ฐ์ผ -> ์ ๋ถ ๋ค ์ค ์ ์๋ค
- ๋ฐ๋ผ์ ๋๋ถ๋ถ ๋ํดํธ ์ฒ๋ฆฌ๋ฅผ ํ๋ ๊ฒ (๋์ค์ ํธ์ถํ ๋๋, ํ ๋๊ฐ ํ๋ผ๋ฏธํฐ๊ฐ๋ง ์ง์ ํ๊ณ ์ถ์ ๋)
- Server
- group_queue๋ก ์ผ์ข ์ DB๋ฅผ ๋ง๋ ๊ฒ
- ํด๋น ํ์ IP ์ฃผ์์ Port ๋ฒํธ ๋ฑ๋ฑ ์ ๋ณด๊ฐ ๋ค์ด์๋ request๋ฅผ ๋ฃ๋๋ค
socketserver ๊ธฐ๋ฐ UDP Echo ์๋น์ค ๊ฐ๋ฐ
- TCP socketserver ์ฒ๋ผ ๊ฐ๋ฐํจ
- ์ฐ๊ฒฐ ์ค์ , ํด์ ๊ณผ์ ์ด ์๋ค
- socketserver.TCPServer ๋์ socket server.UDPServer๋ฅผ ์ฌ์ฉํ์ฌ Echo Server๋ฅผ ๊ฐ๋ฐ
- UDP๋ connection-less ๋ฐฉ์์ผ๋ก connect() ์ ์ฐจ๊ฐ ์์
- Client
- ๋ฉ์ธ์์ ์ฐ๊ฒฐ ์์ฒญ, ํด์ ํ๋ ๋ถ๋ถ์ด ์ฌ๋ผ์ง
- connect() ํจ์ ํธ์ถ X (connection-less)
- Handler์์๋ ์์ ์ด ๊ฑฐ์ ์๋ค. ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ผ๋ฉด, ๋ฐ๋ก print
socketserver ๊ธฐ๋ฐ UDP ์ฑํ ์๋น์ค ๊ฐ๋ฐ
- Connection-less์ธ ๊ด๊ณ๋ก, ์๋ฒ์์ client ๋ค์ ์ ๋ณด๋ฅผ ์ง์ ์ ์ฅํ๊ณ ๊ด๋ฆฌํ๋ ๊ธฐ๋ฅ์ด ํ์ํจ
- UDP๋ TCP ์ฐ๊ฒฐ ํด์ ์ฒ๋ผ ๋งคํํ ๊ฒ์ด ์๋ค -> ์ง์ ๋ง๋ค์ด์ผ ํ๋ค.
- Client๋ค์ด ์ง์ ํน์ ๋ช ๋ น์ด(#REG, #DEREG)์ ํตํด์ ์๋ฒ์ ๋ฑ๋ก/ํด์ ํ๋ ์ ์ฐจ๋ฅผ ๊ตฌํํจ
- ์ผ์ข ์ ํ๋กํ ์ฝ(ํต์ ์ ์ฝ์)์ ๊ฐ์ ๋ก ๋ง๋ ๊ฒ
- ๋ฑ๋ก( #REG)๋ client ๋ค์ ๋ํด์, ํน์ ์ฌ์ฉ์์ ๋ฉ์์ง๊ฐ ๋ชจ๋ ๋ฑ๋ก๋ client๋ค์ ์ ๋ฌ๋ ์ ์๋๋ก ๊ตฌํํจ
'ComputerScience > FullStackProgramming' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[ํ์คํ] Zero message queue (ZMQ) (0) | 2023.04.17 |
---|---|
[ํ์คํ] Application Layer messaging protocol (0) | 2023.04.17 |
[ํ์คํ] TCP Socket programming (1:1) (0) | 2023.04.12 |
[ํ์คํ] TCP - connection-oriented protocol (1) | 2023.04.12 |
[ํ์คํ] UDP - User Datagram Protocol (0) | 2023.04.11 |