Tải bản đầy đủ (.pdf) (13 trang)

Các thao tác cơ bản trong lập trình socket trên windows

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (358.79 KB, 13 trang )

Generated by Foxit PDF Creator © Foxit Software
For evaluation only.

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Ố 6
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


Generated by Foxit PDF Creator © Foxit Software
For evaluation only.

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;

char FAR *

lpVendorInfo; // bỏ qua

// bỏ qua

} WSADATA, *LPWSADATA;
wVersion

Phiên bản Winsock cần khởi động
Lab 4 Lập trình Socket – TCP & UDP


Generated by Foxit PDF Creator © Foxit Software
For evaluation only.

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

Họ

tầng dưới

địa chỉ

IP


Kiểu socket

Nghi thức sử dụng
trên socket

AF_INET TCP

SOCK_STREAM IPPROTO_IP

UDP

SOCK_DGRAM IPPROTO_UDP

Raw

SOCK_RAW

IPPROTO_RAW

Socket
IPPROTO_ICMP
* Giá trị trả về
 socket mới (SOCKET), nếu thành công
Lab 4 Lập trình Socket – TCP & UDP


Generated by Foxit PDF Creator © Foxit Software
For evaluation only.


Khoa Mạng Máy Tính và Truyền Thông – Trường Đại Học CNTT

 INVALID_SOCKET, nếu có lỗi
2.2.2. Kiểm tra và xử lý lỗi
- 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_b4;
}

S_un_b;

struct {
unsigned short s_w1,

s_w2;

Lab 4 Lập trình Socket – TCP & UDP

s_b3,


Generated by Foxit PDF Creator © Foxit Software
For evaluation only.

Khoa Mạng Máy Tính và Truyền Thông – Trường Đại Học CNTT

}

S_un_w;

unsigned long


s_addr;

} S_un;
} 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
Lab 4 Lập trình Socket – TCP & UDP



Generated by Foxit PDF Creator © Foxit Software
For evaluation only.

Khoa Mạng Máy Tính và Truyền Thông – Trường Đại Học CNTT

 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
- Thứ tự network-byte - big-endian form: từ byte cao đến byte thấp
2.2.4.1. Chuyển đổi từ thứ tự host-byte sang thứ tự network-byte
u_long htonl(u_long hostlong)
u_short htons(u_short hostshort)
2.2.4.2. Chuyển đổi từ thứ tự network-byte sang thứ tự host-byte
u_long ntohl(u_long hostlong)
u_short ntohs(u_short hostshort)
2.2.5. Phân giải tên
- Cấu trúc dữ liệu biểu diễn thông tin của một máy tính
typedef struct hostent {
char FAR *

h_name;

char FAR * FAR * h_aliases;
short

h_addrtype;

short


h_length;

char FAR * FAR * h_addr_list;
} HOSTENT, *LPHOSTENT;
 h_name: tên của máy tính.
 h_aliases: mảng các tên khác của máy tính.
 h_addrtype: kiểu của địa chỉ được trả về.
 h_length: chiều dài của mỗi địa chỉ, tính bằng byte.
 h_addr_list: danh sách các địa chỉ của máy tính theo thứ tự networkbyte. Macro h_addr được định nghĩa là h_addr_list[0] để tương
thích với các ứng dụng cũ.
2.2.5.1. Lấy thông tin khi biết tên
- Nhận thông tin về máy tính tương ứng với tên cho trước
Lab 4 Lập trình Socket – TCP & UDP


Generated by Foxit PDF Creator © Foxit Software
For evaluation only.

Khoa Mạng Máy Tính và Truyền Thông – Trường Đại Học CNTT

struct HOSTENT FAR* gethostbyname(
const char FAR * name )
* Các tham số
 name: [in] tên của máy tính cần phân giải.
* Giá trị trả về
 Một cấu trúc HOSTENT, nếu thành công
 NULL, nếu có lỗi
2.2.5.2. Lấy thông tin khi biết địa chỉ IP
- Nhận thông tin về máy tính tương ứng với địa chỉ IP cho trước
struct HOSTENT FAR * gethostbyaddr(

const char FAR * addr, int len, int type )
* Các tham số
 addr: [in] địa chỉ của máy tính theo thứ tự network-byte.
 len: [in] chiều dài của chuỗi địa chỉ
 type: [in] kiểu của địa chỉ, được thiết lập là AF_INET.
* Giá trị trả về
 Một cấu trúc HOSTENT, nếu thành công
 NULL, nếu có lỗi
2.2.6. Thông tin về các dịch vụ
-

Thông

tin

về

các

dịch

vụ

được



tả

\WINNT\system32\drivers\etc\services.

- Cấu trúc SERVENT dùng để mô tả thông tin về một dịch vụ
struct servent {
char FAR *

s_name;

char FAR * FAR *

s_aliases;

short

s_port;

char FAR *

s_proto;
Lab 4 Lập trình Socket – TCP & UDP

trong

tập

tin


Generated by Foxit PDF Creator © Foxit Software
For evaluation only.

Khoa Mạng Máy Tính và Truyền Thông – Trường Đại Học CNTT


};
 s_name: tên của dịch vụ.
 s_aliases: các tên khác.
 s_port: số hiệu cổng của dịch vụ, theo thứ tự network-byte.
 s_proto: tên của giao thức sử dụng cho dịch vụ.
- Để lấy thông tin về một dịch vụ, sử dụng hàm:
struct servent FAR * getservbyname ( const char FAR
*name, const char FAR *proto )
* Các tham số
 name: [in] tên dịch vụ.
 proto: [in] tên giao thức sử dụng. Giá trị NULL chỉ định xét tên dịch vụ.
* Giá trị trả về
 Một cấu trúc SERVENT, nếu thành công
 NULL, nếu có lỗi
2.3. TCP
2.3.1. Gắn địa chỉ cho socket
int bind( SOCKET s,
const struct sockaddr FAR* name,
int namelen )
* Các tham số
 s: [in] socket chưa được gắn kết địa chỉ.
 name: [in] địa chỉ được gán cho socket, một cấu trúc SOCKADDR.
 namelen: [in] kích thước của giá trị tham số name.
* Giá trị trả về
 0, nếu thành công
 SOCKET_ERROR, nếu có lỗi.
2.3.2. Lắng nghe kết nối
Lab 4 Lập trình Socket – TCP & UDP



Generated by Foxit PDF Creator © Foxit Software
For evaluation only.

Khoa Mạng Máy Tính và Truyền Thông – Trường Đại Học CNTT

int listen( SOCKET s, int backlog )
* Các tham số
 s: [in] socket đã được gắn địa chỉ nhưng chưa kết nối.
 backlog: [in] kích thước tối đa của hàng đợi thiết lập kết nối. Giá trị tối
đa được chỉ định bằng hằng số SOMAXCONN.
2.3.3. Chấp nhật thiết lập một kết nối
SOCKET accept( SOCKET s, struct sockaddr FAR* addr,
int FAR*

addrlen )

* Các tham số
 s: [in] socket đang lắng nghe yêu cầu kết nối.
 addr: [out] địa chỉ của socket ở máy client đang thực hiện kết nối.
 addrlen: [out] chiều dài thực sự của addr. Phải khởi tạo giá trị ban đầu là
kích thước của addr
* Giá trị trả về
 Một SOCKET để giao tiếp thực sự với client, nếu thành công
 INVALID_SOCKET, nếu có lỗi
2.3.4. Thiết lập một kết nối
int connect( SOCKET s,
const struct sockaddr FAR* name, int namelen )
* Các tham số
 s: [in] socket chưa kết nối.

 name: [in] socket cần kết nối đến.
 namelen: [in] kích thước của name.
* Giá trị trả về
 0, nếu thành công
 SOCKET_ERROR, nếu có lỗi
2.3.5. Gửi dữ liệu
Lab 4 Lập trình Socket – TCP & UDP


Generated by Foxit PDF Creator © Foxit Software
For evaluation only.

Khoa Mạng Máy Tính và Truyền Thông – Trường Đại Học CNTT

int send( SOCKET s, const char FAR * buf, int len,
int flags )
* Các tham số
 s: [in] socket đã kết nối.
 buf: [in] vùng đệm chứa dữ liệu cần gửi.
 len: [in] chiều dài dữ liệu trong buf.
 flags: [in] chỉ định cách thức truyền dữ liệu, truyền dữ liệu bình thường,
thiết lập giá trị 0.
* Giá trị trả về
 số byte đã gửi đi, nếu thành công
 SOCKET_ERROR, nếu có lỗi.
2.3.6. Nhận dữ liệu
int recv( SOCKET s, char FAR* buf, int len,
int flags )
* Các tham số
 s: [in] socket đã kết nối.

 buf: [out] vùng đệm để lưu dữ liệu nhận.
 len: [in] kích thước vùng đệm buf.
 flags: [in] chỉ định cách thức nhận dữ liệu, nhận dữ liệu bình thường,
thiết lập giá trị 0.
* Giá trị trả về
 số byte dữ liệu nhận được, nếu thành công
 SOCKET_ERROR, nếu có lỗi.
2.3.7. Shutdown
int shutdown( SOCKET s, int how )
* Các tham số
 s: [in] socket cần shutdown.
Lab 4 Lập trình Socket – TCP & UDP


Generated by Foxit PDF Creator © Foxit Software
For evaluation only.

Khoa Mạng Máy Tính và Truyền Thông – Trường Đại Học CNTT

 how: [in] chỉ định những loại thao tác nào không thực hiện nữa.
o SD_RECEIVE: không cho phép gọi các hàm recv() trên socket.
o SD_SEND: không cho phép gọi các hàm send() trên socket.
o SD_BOTH: không cho phép gọi cả send() và recv() trên socket.
* Giá trị trả về
 0, nếu thành công
 SOCKET_ERROR, nếu có lỗi
2.3.8. Đóng socket
int closesocket (SOCKET s)
* Các tham số
 s: [in] socket cần đóng.

2.4. UDP
2.4.1. Nhận dữ liệu
int revcfrom ( SOCKET s, char FAR* buf, int len,
int flags, struct sockaddr FAR* from, int FAR*
fromlen )
*Các tham số
 Bốn tham số đầu tiên giống như mô tả trong hàm recv().
 from: [out] thông tin địa chỉ của máy tính gửi dữ liệu.
 fromlen: [in/out] kích thước của cấu trúc from.
* Giá trị trả về
 số byte thực sự nhận được, nếu thành công
 0, nếu socket đã được đóng đúng cách
 SOCKET_ERROR, nếu có lỗi.
2.4.2. Gửi dữ liệu

Lab 4 Lập trình Socket – TCP & UDP


Generated by Foxit PDF Creator © Foxit Software
For evaluation only.

Khoa Mạng Máy Tính và Truyền Thông – Trường Đại Học CNTT

int sendto( SOCKET s, const char FAR *buf, int len,
int flags, const struct sockaddr FAR *to, int tolen
)
*Các tham số
 buf: [in] dữ liệu cần gửi.
 len: [in] kích thước dữ liệu cần gửi, tính bằng byte.
 to: [in] địa chỉ của máy đích nhận dữ liệu

 tolen: [in] kích thước của cấu trúc to.
 Các tham số khác giống như mô tả trong hàm recvfrom().
* Giá trị trả về
 số byte thực sự được gửi, nếu thành công
 SOCKET_ERROR, nếu có lỗi.
2.5. Các hàm tiện ích khác
2.5.1. Lấy tên của máy tính cục bộ
int gethostname ( char *name, int namelen )
* Các tham số
 name: [out] vùng đệm để lưu tên của máy tính cục bộ.
 namelen: [in] kích thước của vùng đệm.
2.5.2. Lấy thông tin của máy tính ở xa
int getpeername ( SOCKET s, struct sockaddr *name,
int *namelen )
* Các tham số
 s: [in] socket đã được kết nối.
 name: [out] cấu trúc dữ liệu để nhận thông tin socket của máy tính ở xa.
 namelen: [in/out] kích thước của cấu trúc name.
2.5.3. Lấy thông tin của socket cục bộ

Lab 4 Lập trình Socket – TCP & UDP


Generated by Foxit PDF Creator © Foxit Software
For evaluation only.

Khoa Mạng Máy Tính và Truyền Thông – Trường Đại Học CNTT

int getsockname ( SOCKET s, struct sockaddr *name,
int *namelen )

* Các tham số
 s: [in] socket cần lấy tên.
 name: [out] thông tin của socket.
 namelen: [in/out] kích thước của vùng đệm name.

* Ghi chú :
Nếu hệ thống không có thư viện Winsock2, cần sử dụng thư viện wsock32.lib

+ đối với VC++ : chọn Project – Add to Project – File , chọn File of type :
dạng file .lib . chọn đường dẫn đến tập tin …\ VC98\Lib\WS2_32.lib

+ đối với .net 2003 , 2005 : chọn Properties – Configuration Properties –
Linker – Command Line . nhập WS2_32.lib vào ô Additional option

Lab 4 Lập trình Socket – TCP & UDP



×