Chương 2: Lập trình mạng trong windows
Chương 2
1. Giới thiệu thư viện winsock
- Giao tiếp lập trình mạng cho phép phát triển ứng dụng giao tiếp trên cùng
một máy hoặc nhiều máy khác nhau thông qua môi trường mạng
- Winsock được hỗ trợ sẵn trong windows cho phép lập trình mạng với giao
thức TCP/IP hoặc IPX
- Lập trình Winsock trong windows ta sử dụng thư viện WINSOCK2.H,
WS2_32.LIB
- Phiên bản winsock hỗ trợ cho các hệ điều hành Windows như sau:
Chương 2
1. Giới thiệu thư viện winsock
Khởi động Winsock
- Trước khi chạy ứng dụng winsock cần khởi động thư viện winsock, winsock
DLL bằng hàm WSAStartup
int WSAStartup(
WORD wVersionRequested,
LPWSADATA lpWSAData
);
wVersionRequested : version của winsock
lpWSAData : trỏ tới struct LPWSADATA
Chương 2
1. Giới thiệu thư viện winsock
Khởi động Winsock
- typedef struct WSAData
{
WORD wVersion;
WORD wHighVersion;
char szDescription[WSADESCRIPTION_LEN + 1];
char szSystemStatus[WSASYS_STATUS_LEN + 1];
unsigned short iMaxSockets;
unsigned short iMaxUdpDg;
char FAR * lpVendorInfo;
} WSADATA, * LPWSADATA;
Chương 2
1. Giới thiệu thư viện winsock
Kết thúc Winsock
Gọi hàm int WSACleanup(void);
Chương 2
2. Tạo socket trong windows
- Cú pháp
SOCKET socket (
int af,
int type,
int protocol
);
af: họ địa chỉ giao thức, thiết lập là AF_INET nếu ta sử dụng IPv4
type: kiểu giao thức của socket, thiết lập là SOCK_STREAM cho TCP/IP,
SOCK_DGRAM cho UDP/IP
Protocol: thiết lập là IPPROTO_TCP đối với TCP, IPPROTO_UDP đối với
UDP
Chương 2
2. Tạo socket trong windows
- Địa chỉ
winsock quản lý địa chỉ thông qua SOCKADDR_IN structure
SOCKADDR_IN structure có dạng sau
struct sockaddr_in
{
short sin_family;
u_short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
sin_family : AF_INET
sin_addr : lưu trữ địa chỉ IP
sin_port : port
sin_zero : make the SOCKADDR_IN structure the same size as the SOCKADDR structure.
Chương 2
3. Xây dựng chương trình giao tiếp có kết nối
dùng winsock
Server client
socket socket
bind Address
resolution
listen connect
accept
Chương 2
3. Xây dựng chương trình giao tiếp có kết nối
dùng winsock
3.1 Server
binding:
int bind(
SOCKET s,
const struct sockaddr FAR* name,
int namelen
);
Khi socket được tạo ra cần dùng hàm bind để bind tới địa chỉ
s: socket
name: kiểu địa chỉ socket struct sockaddr
namelen: kích thước của name
Chương 2
3. Xây dựng chương trình giao tiếp có kết nối
dùng winsock
Đoạn lệnh tạo socket và bind
SOCKET s;
SOCKADDR_IN tcpaddr;
int port = 5150;
s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
tcpaddr.sin_family = AF_INET;
tcpaddr.sin_port = htons(port);
tcpaddr.sin_addr.s_addr = htonl(INADDR_ANY);
bind(s, (SOCKADDR *)&tcpaddr, sizeof(tcpaddr));
Chương 2
3. Xây dựng chương trình giao tiếp có kết nối
dùng winsock
Listenning: lắng nghe kết nối từ client
int listen(
SOCKET s,
int backlog
);
backlog : chiều dài tối đa của hàng đợi kết nối
Chương 2
3. Xây dựng chương trình giao tiếp có kết nối
dùng winsock
accepting: chấp nhận kết nối
SOCKET accept(
SOCKET s,
struct sockaddr FAR* addr,
int FAR* addrlen
);
addrlen: tham chiếu tới kích thước của SOCKADDR_IN structure
Chương 2
3. Xây dựng chương trình giao tiếp có kết nối
dùng winsock
Chương trình phía server:
#include
#pragma comment(lib, "wsock32.lib")
void main(void)
{
WSADATA wsaData;
SOCKET ListeningSocket;
SOCKET NewConnection;
SOCKADDR_IN ServerAddr;
SOCKADDR_IN ClientAddr;
int Port = 5150;
// Initialize Winsock version 2.2
WSAStartup(MAKEWORD(2,2), &wsaData);
Chương 2
3. Xây dựng chương trình giao tiếp có kết nối
dùng winsock
Chương trình phía server:
// Create a new socket to listen for client connections.
ListeningSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
// Set up a SOCKADDR_IN structure that will tell bind that we
ServerAddr.sin_family = AF_INET;
ServerAddr.sin_port = htons(Port);
ServerAddr.sin_addr.s_addr = htonl(INADDR_ANY);
// Associate the address information with the socket using bind.
bind(ListeningSocket, (SOCKADDR *)&ServerAddr, sizeof(ServerAddr));
// Accept a new connection when one arrives.
NewConnection = accept(ListeningSocket, (SOCKADDR *)
&ClientAddr,&ClientAddrLen));
// At this point you can do two things with these sockets. Wait
// for more connections by calling accept again on ListeningSocket
// and start sending or receiving data on NewConnection
Chương 2
3. Xây dựng chương trình giao tiếp có kết nối
dùng winsock
Chương trình phía server:
closesocket(NewConnection);
closesocket(ListeningSocket);
// When your application is finished handling the connections,
// call WSACleanup.
WSACleanup();
Chương 2
3. Xây dựng chương trình giao tiếp có kết nối
dùng winsock
3.2 Client
#include
#pragma comment(lib, "wsock32.lib")
void main(void)
{
WSADATA wsaData;
SOCKET s;
SOCKADDR_IN ServerAddr;
int Port = 5150;
// Initialize Winsock version 2.2
WSAStartup(MAKEWORD(2,2), &wsaData);
// Create a new socket to make a client connection.
Chương 2
3. Xây dựng chương trình giao tiếp có kết nối
dùng winsock
3.2 Client
#include
#pragma comment(lib, "wsock32.lib")
void main(void)
{
WSADATA wsaData;
SOCKET s;
SOCKADDR_IN ServerAddr;
int Port = 5150;
// Initialize Winsock version 2.2
WSAStartup(MAKEWORD(2,2), &wsaData);
// Create a new socket to make a client connection.
s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
Chương 2
3. Xây dựng chương trình giao tiếp có kết nối
dùng winsock
3.2 Client
// server IP: 136.149.3.29
ServerAddr.sin_family = AF_INET;
ServerAddr.sin_port = htons(Port);
ServerAddr.sin_addr.s_addr = inet_addr("136.149.3.29");
// Make a connection to the server with socket s.
connect(s, (SOCKADDR *) &ServerAddr, sizeof(ServerAddr));
// At this point you can start sending or receiving data on
// the socket s. We will describe sending and receiving data
closesocket(s);
// When your application is finished handling the connection, call
// WSACleanup.
WSACleanup(); }
Chương 2
4. Truyền/nhận dữ liệu
Hàm send và WSASend (dùng cho socket version 2)
Hàm send:
int send(
SOCKET s,
const char FAR * buf,
int len,
int flags
);
buf : bộ đệm truyền dữ liệu
flags: trạng thái send MSG_DONTROUTE, or MSG_OOB
Chương 2
4. Truyền/nhận dữ liệu
Hàm WSASend :
int WSASend(
SOCKET s,
LPWSABUF lpBuffers,
DWORD dwBufferCount,
LPDWORD lpNumberOfBytesSent,
DWORD dwFlags,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);
lpBuffers : buffer kiếu LPWSABUF
dwBufferCount : số lượng buffer
lpNumberOfBytesSent : số lượng bytes đã truyền
dwFlags: số bản sao
lpOverlapped and lpCompletionRoutine : thông số về đường truyền I/O