Software Development Architectures
When building software applications, developers must create both client and server components.
- Server: Provides continuous, around-the-clock services
- Client: Initiates requests to locate and consume services
Two primary architectural patterns exist:
C/S Architecture (Client/Server)
Examples: Desktop QQ application, mobile games like Honor of Kings
Advantages:
- Stable performance
- Efficient network resource utilization
Disadvantages:
- Multiple applications require multiple client installations
- Each update requires users to download and install new versions
B/S Architecture (Browser/Server)
Examples: Web-based applications accessed through browser URLs
Advantages:
- Browser serves as the universal client
- No software installation required
- Updates deployed server-side without user intervention
Disadvantages:
- Higher network bandwidth consumption
- Application stability depends on network connectivity
The OSI Seven-Layer Protocol
Historical Context
Network programming emerged from military research seeking remote data access capabilities.
Early remote communication methods:
- Telephone systems using copper wires
- Computers connected via network cables and network interface cards
Two fundamental requirements for remote communication:
- Physical transmission medium (network card)
- Network protocols enabling inter-computer communication
Network Protocol Structure
The OSI model defines seven distinct layers:
Application Layer
Protocols: HTTP, FTP
Transport Layer
Protocols: TCP, UDP
- Port numbers identify specific applications on a computer
- Valid range: 0 to 65535
- Operating systems reserve ports 0-1024
- Recommended: use ports above 8000 for custom applications
Common default ports:
| Service | Port |
|---|---|
| MySQL | 3306 |
| MongoDB | 27017 |
| Django | 8000 |
| Tomcat | 8080 |
| Flask | 5000 |
| Redis | 6379 |
Communication requires establishing bidirectional channels: one for client-to-server messages, another for server-to-client responses.
Network Layer
- IP addresses uniquely identify computers within networks
- Format: dotted decimal notation
- Range: 0.0.0.0 to 255.255.255.255
- IPv4: Currently predominant protocol version
- IPv6: Extended addressing to accommodate growing device counts
- Localhost: 127.0.0.1 (loopback address)
Data Link Layer
The Ethernet protocol governs electrical signal transmission for binary data.
Ethernet Protocol Features:
- Defines packet formatting for electrical signals
- Every networked device requires a network card with unique MAC address (first six digits indicate manufacturer, last six digits form serial number)
Switching Equipment:
- Connects multiple computers in a network
- Operates through broadcasting and unicast mechanisms
- Limitations: broadcast storms, inability to cross network boundaries
Internet: Enables communication between separate local networks.
Physical Layer
Handles raw binary data transmission via electrical signals.
TCP Protocol Mechanics
Connection Establishment: Three-Way Handshake
Establishing bidirectional communication involves:
- listen: Server enters listening state
- established: Client confirms connection request
Connection Termination: Four-Way Handshake
When terminating connections:
- Server acknowledges the disconnection request
- After processing remaining data, server sends final confirmation
- Connection enters TIME_WAIT state
Stream-Based Protocol Characteristics
TCP operates as a stream protocol where data flows continuously without message boundaries. The client sends data, and the server must acknowledge receipt. If acknowledgments fail to arrive, the client retries transmission; persistent failures result in dropped data.
Socket Fundamentals
Definition
The socket module enables developers to build client-server architecture applications with minimal protocol complexity.
Purpose
Sockets abstract the underlying protocol implementations across all network layers, allowing developers to focus on application logic rather than network mechanics.
TCP Implementation
Server Implementation
import socket
def start_server():
# Create TCP socket instance
server_sock = socket.socket()
# Bind to loopback address and port
server_sock.bind(('127.0.0.1', 9000))
# Enable listening with connection queue
server_sock.listen(5)
# Accept incoming connections
client_conn, client_addr = server_sock.accept()
print(f"Connection established from: {client_addr}")
# Receive and process data
incoming_data = client_conn.recv(1024).decode('utf-8')
print(f"Received: {incoming_data}")
# Send response back to client
client_conn.send(b'Server acknowledged your message')
# Clean up connections
client_conn.close()
server_sock.close()
if __name__ == '__main__':
start_server()
Client Implementation
import socket
def connect_to_server():
# Initialize client socket
client_sock = socket.socket()
# Establish connection to server
client_sock.connect(('127.0.0.1', 9000))
# Send message to server
message = 'Greetings from client'
client_sock.send(message.encode('utf-8'))
# Receive server response
response = client_sock.recv(1024)
print(f"Server response: {response}")
# Close client socket
client_sock.close()
if __name__ == '__main__':
connect_to_server()
Critical Constraint: Communication must follow alternating send/receive patterns. Simultaneous sending or receiving on both ends causes blocking without errors.
Connection Pool with Persistent Communication
Server with Multi-Client Support
import socket
def run_persistent_server():
server_sock = socket.socket()
server_sock.bind(('127.0.0.1', 9000))
server_sock.listen(5) # Queue capacity: 5 pending + 1 active
while True:
client_conn, client_addr = server_sock.accept()
print(f"Client connected: {client_addr}")
try:
while True:
data = client_conn.recv(1024).decode('utf-8')
if not data or data == 'q':
break
print(f"From client: {data}")
reply = input('Enter response: ')
client_conn.send(reply.encode('utf-8'))
except Exception as error:
print(f"Client error: {error}")
finally:
client_conn.close()
if __name__ == '__main__':
run_persistent_server()
Client with Continuous Communication
import socket
def run_client():
client_sock = socket.socket()
client_sock.connect(('127.0.0.1', 9000))
while True:
outgoing = input('Message to send: ')
client_sock.send(outgoing.encode('utf-8'))
if outgoing == 'q':
break
incoming = client_sock.recv(1024).decode('utf-8')
print(f"Server response: {incoming}")
client_sock.close()
if __name__ == '__main__':
run_client()
Key Concepts Summary
| Concept | Purpose |
|---|---|
| IP Address | Uniquely identifies a computer's network location |
| Port Number | Identifies a specific application on that computer |
| IP + Port | Globally identifies a specific application on a specific machine |
Socket programming provides the foundational building blocks for creating networked applications across various protocols and communication patterns.