# HW11 多緒網路程式設計作業
## 練習1
### 通過畫面截圖

### 程式碼 Server
```python=
import socket
import threading
MaxClient = 10
def ThreadMain(threadArgs):
clntIndex = threadArgs['clntIndex']
clntSocki = threadArgs['Sock']
echoBuffer = bytearray(1000)
while True:
recvMsgSize = clntSocki.recv_into(echoBuffer, 1000)
# 尋找可用的客戶端索引
if recvMsgSize <= 0:
threadArgs['Totalclnt'] -= 1
threadArgs['clntSock'][clntIndex] = 0
print(f"Connection[socket:{clntSocki}] closed. (Current Client:{threadArgs['Totalclnt']})")
break
clntSocki.sendall(echoBuffer[:recvMsgSize])
clntSocki.close()
threadArgs['clntSock'][clntIndex] = 0
def main():
threadArgs = {
'clntIndex': 0,
'clntSock': [0] * MaxClient,
'Totalclnt': 0,
'Sock': None
}
servSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
servSock.bind(('127.0.0.1', 5678))
servSock.listen(3)
print("Server is waiting for clients.")
while True:
Sock, addr = servSock.accept()
for i in range(MaxClient):
if threadArgs['clntSock'][i] == 0:
threadArgs['clntIndex'] = i
break
threadArgs['Sock'] = Sock
threadArgs['clntSock'][i] = Sock
threadArgs['Totalclnt'] += 1
thread = threading.Thread(target=ThreadMain, args=(threadArgs,))
thread.start()
print(f"New client with thread ID: {thread.ident} and socket:{threadArgs['clntSock'][i]} (Current Client:{threadArgs['Totalclnt']})")
if __name__ == "__main__":
main()
```
### 程式碼 Client
```python=
import socket
import time
MAXLINE = 1024
def main():
serv = ('127.0.0.1', 5678) # 伺服器的 IP 位址和埠號
message = "I love NP!!".encode('utf-8') # 要發送的訊息
sd = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 建立 TCP socket
sd.connect(serv) # 連接到伺服器
while True:
str_msg = "How are you?".encode('utf-8') # 要發送的訊息
sd.sendall(str_msg) # 發送訊息到伺服器
print(f"send: {str_msg.decode('utf-8')}")
data = sd.recv(MAXLINE) # 接收從伺服器返回的訊息
if not data: # 如果沒有接收到訊息,則跳出迴圈
break
str_data = data.decode('utf-8') # 解碼接收到的訊息
print(f"recv: {str_data}")
time.sleep(1) # 程式暫停 1 秒
sd.close() # 關閉 socket
if __name__ == "__main__":
main()
```
## 練習2
### 通過畫面截圖

### 程式碼 Server
```python=
import socket
import threading
MaxClient = 10
def ThreadMain(threadArgs):
clntIndex = threadArgs['clntIndex'] # 客戶端索引
clntSocki = threadArgs['Sock'] # 客戶端 socket
echoBuffer = bytearray(1000) # 接收和發送資料的緩衝區
while True:
recvMsgSize = clntSocki.recv_into(echoBuffer, 1000) # 接收客戶端傳送的資料
if recvMsgSize <= 0: # 如果接收到的資料大小小於等於 0,表示客戶端斷開連接
threadArgs['Totalclnt'] -= 1 # 總客戶端數減 1
threadArgs['clntSock'][clntIndex] = 0 # 清除客戶端 socket
print(f"Connection [socket:{clntSocki}] closed. (Current Client:{threadArgs['Totalclnt']})")
break
clntSocki.sendall(echoBuffer[:recvMsgSize]) # 將接收到的資料回傳給客戶端
clntSocki.close() # 關閉客戶端 socket
threadArgs['clntSock'][clntIndex] = 0 # 清除客戶端 socket
def main():
threadArgs = {
'clntIndex': 0, # 客戶端索引
'clntSock': [0] * MaxClient, # 客戶端 socket 列表
'Totalclnt': 0, # 目前連接的客戶端數量
'Sock': None # 當前處理的客戶端 socket
}
servSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 建立 TCP socket
servSock.bind(('0.0.0.0', 5678)) # 綁定伺服器 IP 位址和埠號
servSock.listen(3) # 監聽連接請求
print("Server is waiting for clients.")
while True:
Sock, addr = servSock.accept() # 接受客戶端連接請求
for i in range(MaxClient):
if threadArgs['clntSock'][i] == 0: # 找到空閒的客戶端位置
threadArgs['clntIndex'] = i # 設置客戶端索引
break
threadArgs['Sock'] = Sock # 設置處理的客戶端 socket
threadArgs['clntSock'][i] = Sock # 設置客戶端 socket
threadArgs['Totalclnt'] += 1 # 客戶端數量加 1
thread = threading.Thread(target=ThreadMain, args=(threadArgs,)) # 創建新的執行緒處理客戶端連接
thread.start() # 啟動執行緒
print(f"New client with thread ID: {thread.ident} and socket:{threadArgs['clntSock'][i]} (Current Client:{threadArgs['Totalclnt']})")
if __name__ == "__main__":
main()
```
### 程式碼 Client
```python=
import socket
import time
MAXLINE = 1024
def main():
serv = ('127.0.0.1', 5678) # 伺服器的 IP 位址和埠號
message = "I love NP!!".encode('utf-8') # 要發送的訊息
sd = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 建立 TCP socket
sd.connect(serv) # 連接到伺服器
while True:
str_msg = "How are you?".encode('utf-8') # 要發送的訊息
sd.sendall(str_msg) # 發送訊息到伺服器
print(f"send: {str_msg.decode('utf-8')}")
data = sd.recv(MAXLINE) # 接收從伺服器返回的訊息
if not data: # 如果沒有接收到訊息,則跳出迴圈
break
str_data = data.decode('utf-8') # 解碼接收到的訊息
print(f"recv: {str_data}")
time.sleep(1) # 程式暫停 1 秒
sd.close() # 關閉 socket
if __name__ == "__main__":
main()
```
## 練習3
### 通過畫面截圖

### 程式碼 Server
```python=
import socket
import threading
MaxClient = 10
def ThreadMain(threadArgs):
clntIndex = threadArgs['clntIndex']
clntSocki = threadArgs['Sock']
echoBuffer = bytearray(1000)
while True:
recvMsgSize = clntSocki.recv_into(echoBuffer, 1000)
if recvMsgSize <= 0:
threadArgs['Totalclnt'] -= 1
threadArgs['clntSock'][clntIndex] = 0
print(f"Connection[socket:{clntSocki}] closed. (Current Client:{threadArgs['Totalclnt']})")
break
clntSocki.sendall(echoBuffer[:recvMsgSize])
clntSocki.close()
threadArgs['clntSock'][clntIndex] = 0
def main():
threadArgs = {
'clntIndex': 0,
'clntSock': [0] * MaxClient,
'Totalclnt': 0,
'Sock': None
}
servSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
servSock.bind(('0.0.0.0', 5678))
servSock.listen(3)
print("Server is waiting for clients.")
while True:
Sock, addr = servSock.accept()
for i in range(MaxClient):
if threadArgs['clntSock'][i] == 0:
threadArgs['clntIndex'] = i
break
threadArgs['Sock'] = Sock
threadArgs['clntSock'][i] = Sock
threadArgs['Totalclnt'] += 1
thread = threading.Thread(target=ThreadMain, args=(threadArgs,))
thread.start()
print(f"New client with thread ID: {thread.ident} and socket:{threadArgs['clntSock'][i]} (Current Client:{threadArgs['Totalclnt']})")
if __name__ == "__main__":
main()
```
### 程式碼 Client
```python=
import socket
import threading
def ThreadMain(threadArgs):
sd = threadArgs.sd
str_buffer = bytearray(1024)
while True:
n = sd.recv_into(str_buffer)
if n <= 0:
break
print(f"recv: {str_buffer[:n].decode()}")
sd.close()
threadArgs.close()
def main():
servAddr = ('127.0.0.1', 5678)
sd = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sd.connect(servAddr)
threadArgs = threading.Thread(target=ThreadMain, args=(sd,))
threadArgs.start()
while True:
str_input = input()
sd.sendall(str_input.encode())
if __name__ == "__main__":
main()
```
## 心得
第三題不知道為甚麼寫不出來,Debug很久了也寫不出來