Khoa Mạng Máy Tính và Truyền Thông – Trường Đại Học CNTT
BÀI THỰC HÀNH SỐ 4
Các thao tác cơ bản trong lập trình socket trên windows
Yêu cầu thực hành: Viết các chương trình thực hành các lệnh trong bài thực
hành này. Tham khảo các chương trình mẫu kèm theo bài thực hành.
1. Cơ chế gọi hàm khi trong lập trình socket
1.1. TCP
Hình. Lập trình socket sử dụng TCP
1.2. UDP
- Với giao thức UDP, không cần phải thiết lập kết nối trước khi truyền nhận dữ
liệu
• Chương trình server không sử dụng hai hàm listen() và accept()
• Chương trình client không cần sử dụng hàm connect().
- Sử dụng hàm sendto() thay cho hàm send() trong TCP
- Sử dụng hàm recvfrom() thay cho recv() trong TCP
Lab 4 Lập trình Socket – TCP & UDP
Khoa Mạng Máy Tính và Truyền Thông – Trường Đại Học CNTT
- Client có thể sử dụng hàm connect() để gắn kết cục bộ địa chỉ của máy
tính ở xa với một socket cục bộ và sau đó có thể sử dụng hai hàm send() và
receive() để truyền, nhận dữ liệu; tuy nhiên không có kết nối nào được
thiết lập.
2. Thư viện lập trình Winsock
2.1. Khởi động và đóng thư viện
2.1.1. Khởi động Winsock
- Khởi động thư viện Winsock trước khi thực hiện các thao tác khác
int WSAStartup(WORD wVersionRequested, LPWSADATA lp
WSAData);
* Các tham số
• wVersionRequested: [in] phiên bản của thư viện Winsock cần phải khởi
động. Giá trị này gồm 2 byte: byte thấp chỉ số phiên bản chính, byte cao
chỉ số phiên bản phụ. Giá trị này có thể được chỉ định rõ (0x0202) hoặc
dùng macro MAKEWORD(2,2).
• lpWSAData: [out] thông tin về thư viện Winsock đã được khởi động,
trong đó có chứa phiên bản Winsock.
typedef struct WSAData {
WORD wVersion;
WORD wHighVersion;
char szDescription[WSADESCRIPTION_LEN+1];
char szSystemStatus[WSASYS_STATUS_LEN+1];
unsigned short iMaxSockets; // bỏ qua
unsigned short iMaxUdpDg; // bỏ qua
char FAR * lpVendorInfo; // bỏ qua
} WSADATA, *LPWSADATA;
wVersion
Phiên bản Winsock cần khởi động
Lab 4 Lập trình Socket – TCP & UDP
Khoa Mạng Máy Tính và Truyền Thông – Trường Đại Học CNTT
wHighVersion
Phiên bản Winsock đã khởi động
szDescription
Chủ đề của thư viện đã khởi động
szSystemStatus
Trạng thái hay thông tin cấu hình
* Giá trị trả về
• bằng 0, nếu thành công
• khác 0, nếu có lỗi. Hàm WSAGetLastError() dùng để xác định lỗi.
2.1.2. Đóng thư viện Winsock
- Đóng thư viện Winsock và giải phóng tài nguyên
int WSACleanup(void)
2.2. Window socket
2.2.1. Tạo socket
SOCKET socket ( int af, int type, int protocol )
* Các tham số
• af: [in] mô tả họ địa chỉ.
• type: [in] kiểu của socket.
o SOCK_STREAM: TCP socket
o SOCK_DGRAM: UDP socket
• protocol: [in] nghi thức được sử dụng trên socket.
Nghi thức
tầng dưới
Họ
địa chỉ
Kiểu socket
Nghi thức sử dụng
trên socket
IP AF_INET TCP SOCK_STREAM IPPROTO_IP
UDP SOCK_DGRAM IPPROTO_UDP
Raw
Socket
SOCK_RAW IPPROTO_RAW
IPPROTO_ICMP
* Giá trị trả về
• socket mới (SOCKET), nếu thành công
• INVALID_SOCKET, nếu có lỗi
2.2.2. Kiểm tra và xử lý lỗi
Lab 4 Lập trình Socket – TCP & UDP
Khoa Mạng Máy Tính và Truyền Thông – Trường Đại Học CNTT
- Giá trị lỗi trả về trong các lời gọi hàm Winsock không thành công thường là
SOCKET_ERROR (-1). Để lấy chi tiết mã lỗi, sử dụng hàm:
int WSAGetLastError (void)
* Giá trị trả về
• Các hằng số lỗi WSAE được định nghĩa trong tập tin Winsock.h hoặc
Winsock2.h
2.2.3. Internet Address
- Sử dụng cấu trúc SOCKADDR_IN để chỉ định thông tin về địa chỉ IP và
cổng dịch vụ
typedef struct sockaddr_in{
short sin_family;
unsigned short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
} SOCKADDR_IN;
• sin_family: họ địa chỉ, phải được thiết lập là AF_INET.
• sin_port: cổng dịch vụ.
• sin_addr: địa chỉ IP được chỉ định theo cấu trúc sau:
typedef struct in_addr {
union {
struct{
unsigned char s_b1, s_b2, s_b3, s_b4;
} S_un_b;
struct {
unsigned short s_w1, s_w2;
} S_un_w;
unsigned long s_addr;
} S_un;
Lab 4 Lập trình Socket – TCP & UDP
Khoa Mạng Máy Tính và Truyền Thông – Trường Đại Học CNTT
} SOCKADDR;
• sin_zero: 8 byte 0 được thêm vào để tạo ra một cấu trúc có cùn kích
thước với SOCKADDR.
- Địa chỉ INADDR_ANY chỉ định server “lắng nghe” yêu cầu từ client trên tất
cả các card mạng.
- Địa chỉ INADDR_BROADCAST dùng để gửi các gói tin UDP broadcast. Để
sử dụng giá trị này, socket phải được thiết lập tùy chọn SO_BROADCAST.
2.2.3.1. Chuyển đổi địa chỉ IP từ chuỗi sang số
- Chuyển đổi một chuỗi biểu diễn địa chỉ IP sang một số nguyên 32 bit.
unsigned long inet_addr(const char FAR *cp)
* Các tham số
• cp: [in] chuỗi biểu diễn địa chỉ IP.
* Giá trị trả về
• số nguyên (unsigned long) biểu diễn địa chỉ IP theo thứ tự network-byte.
• INADDR_NONE, nếu có lỗi
2.2.3.1. Chuyển đổi địa chỉ IP từ số sang chuỗi
- Chuyển đổi địa chỉ IP số sang một chuỗi biểu diễn địa chỉ IP. Sau khi chuyển
đổi địa chỉ xong nên sao chép giá trị trả về sang một vùng nhớ khác để tránh
mất dữ liệu khi gọi thực hiện các hàm Winsock khác.
char FAR * inet_ntoa ( struct in_addr in )
* Các tham số
• in: [in] cấu trúc biểu diễn địa chỉ Internet của một máy tính.
* Giá trị trả về
• Chuỗi biểu diễn địa chỉ IP, nếu thành công
• NULL, nếu không thành công
2.2.4. Thứ tự byte
- Thứ tự host-byte - little-endian form: từ byte thấp đến byte cao
Lab 4 Lập trình Socket – TCP & UDP