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
Trang 21 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 32LIB
Phiên bản winsock hỗ trợ cho các hệ điều hành Windows như sau:
Trang 3wVersionRequested : version cua winsock
loWSAData : tro toi struct LPWSADATA
Trang 4char szDescription[WSADESCRIPTION_ LEN + 1];
char szSystemStatus[WSASYS_ STATUS _LEN + 1];
unsigned short iMaxSockets;
unsigned short iMaxUdpDg;
char FAR * lpVendorlInfo;
} WSADATA, * LPWSADATA;
Trang 5
Goiham ¡nt WSACleanup(void);
Trang 6af: 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 lap la IPPROTO_TCP déi voi TCP, IPPROTO_UDP déi voi
UDP
Trang 7winsock quan ly dia chi th6ng qua SOCKADDR_IN structure
SOCKADDR_IN structure co dang sau
struct sockaddr_in
Ẳ
short sin_ family;
u_ short sin_ port;
struct in_addr sin_ addr;
Trang 83 Xây dựng chương trình giao tiếp có kết nồi
dùng winsock
Trang 9name: kiểu địa chỉ socket struct sockaddr
namelen: kích thước của name
Trang 12struct sockaddr FAR”® addr,
int FAR* addrlen
);
addrlen: tham chiéu toi kich thué@c cia SOCKADDR IN structure
Trang 14Chươ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, (GOCKADDR *)
&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
Trang 17// Create a new socket to make a client connection
s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP):
Trang 18// 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(); }
Trang 19buf : bộ đệm truyền dữ liệu
flags: trang thaisend MSG DONTROUTE, or MSG OOB
Trang 20IpBuffers : buffer kiều LPWSABUF
dwBufferCourt : số lượng buffer
IpNumberOfBytesSernt : số lượng bytes đã truyền
dwFlags: số bản sao
IpOverlapped and IpCompletionRoutine : thông số về đường truyền I/O
Trang 21int nBytes = 2048, nLeft, idx;
// Fill sendbuff with 2048 bytes of data
// Assume s Is a valid, connected stream socket
Trang 245 Xây dựng chương trình giao tiệp không kết
nồi dùng winsock
Trang 25struct sockaddr FAR* from,
int FAR* fromlen
);
flags : MSG_OOB or MSG_PEEK
Trang 26int SenderAddrSize = sizeof(SenderAdd)r);
// Initialize Winsock version 2.2
\AIS A StartiinfMAKFANORI(D OV RweaNata\:
Trang 27
Vi du ham recvfrom
// Create a new socket to receive datagrams on
ReceivingSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
// Set up a SOCKADDR_IN structure that will tell bind that we
// want to receive datagrams from all interfaces using port
// 5150
ReceiverAddr.sin_family = AF_INET;
ReceiverAddr.sin_port = htons(Port);
ReceiverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
/! Associate the address information with the socket using bind
bind(ReceivingSocket, (SOCKADDR *)&SenderAddr, sizeof(SenderAddr));
Trang 28// At this point you can receive datagrams on your bound socket
recvfrom(ReceivingSocket, ReceiveBuf, BufLength, 0, (SOCKADDR *)&SenderAddr,
Trang 30// Create a new socket to receive datagrams on
sendinaSocket = socket(AF INET SOCK DGRAM IPPROTO UDP):
Trang 31
ReceiverAddr.sin_port = htons(Port);
ReceiverAddr.sin_addr.s_addr = inet_addr("136.149.3.29");
// Send a datagram to the receiver
sendto(SendingSocket, SendBuf, BufLength, 0, (SOCKADDR *)&ReceiverAddr,
Trang 33
sẽ bị chờ mãi mãi
Giải pháp khác phục: tạo luồng nhận và xử lý riêng rẽ
Trang 34
#define MAX_BUFFER_SIZE 4096
// Initialize critical section (data) and create
// an auto-reset event (hEvent) before creating the
Trang 35nLeft = NUM_BYTES REQUIRED;
// However many bytes constitutes
// enough data for processing
// (i.e non-zero)
Trang 37// Remove the processed data from the input
// buffer, and shift the remaining data to
// the start of the array
nBytes -= NUM_BYTES_REQUIRED;
LeaveCriticalSection(&data);
}