Winsock基础篇(未完待续)
int
WSAStartup(
WORD wVersionRequested, // MAKEWORD(x, y), x=>minor version, y=>major version
LPWSADATA lpWSAData // pointer to
);
typedef struct WSAData
{
WORD wVersion; //seted by WSAStartup
WORD wHighVersion; //
char szDescription[WSADESCRIPTION_LEN + 1]; //n't really useful
char szSystemStatus[WSASYS_STATUS_LEN + 1]; //n't really useful
unsigned short iMaxSockets; //Do not use. maximum number of concurrently open sockets.
unsigned short iMaxUdpDg; //Do not use. the maximum datagram size
char FAR * lpVendorInfo; //not used
} WSADATA, * LPWSADATA;
// skeleton Winsock application
#include < winsock2.h >
void main( void )
{
WSADATA wsaData;
// Initialize Winsock version 2.2
if ((Ret = WSAStartup(MAKEWORD(2,2), &wsaData)) != 0)
{
// NOTE: Since Winsock failed to load we cannot use
// WSAGetLastError to determine the specific error for
// why it failed. Instead we can rely on the return
// status of WSAStartup.
printf("WSAStartup failed with error %d\n", Ret);
return;
}
// Setup Winsock communication code here
// When your application is finished call WSACleanup
if (WSACleanup() == SOCKET_ERROR)
{
printf("WSACleanup failed with error %d\n", WSAGetLastError());//flip side of which is WSASetLastError
}
}
// SOCKADDR_IN, when want to listen for incoming client requests
struct sockaddr_in
{
short sin_family; //must be AF_INET, for IP
u_short sin_port; //port
struct in_addr sin_addr; //4 byte
char sin_zero[8];//padding to make SOCKADDR_IN same size as SOCKADDR
} ;
// convert "*.*.*.*" to 32-bit unsigned long integer
unsigned long inet_addr(
const char FAR * cp
);
// ------------------------sin initialize - block start--------------------------- //
SOCKADDR_IN InternetAddr;
INT nPortId = 5150 ;
InternetAddr.sin_family = AF_INET;
// Convert the proposed dotted Internet address 136.149.3.29
// to a four-byte integer, and assign it to sin_addr
InternetAddr.sin_addr.s_addr = inet_addr( " 136.149.3.29 " );
// The nPortId variable is stored in host-byte order. Convert
// nPortId to network-byte order, and assign it to sin_port.
InternetAddr.sin_port = htons(nPortId);
// ------------------------sin initialize - block end--------------------------- //
// ------------------------convert functions - block start--------------------------- //
// host-byte => network-byte
u_long htonl(u_long hostlong);
int WSAHtonl(
SOCKET s,
u_long hostlong,
u_long FAR * lpnetlong
);
u_short htons(u_short hostshort);
int WSAHtons(
SOCKET s,
u_short hostshort,
u_short FAR * lpnetshort
);
// network-byte => host-byte
u_long ntohl(u_long netlong);
int WSANtohl(
SOCKET s,
u_long netlong,
u_long FAR * lphostlong
);
u_short ntohs(u_short netshort);
int WSANtohs(
SOCKET s,
u_short netshort,
u_short FAR * lphostshort
);
// ------------------------convert functions - block end--------------------------- //
SOCKET socket (
int af, // AF_INET for IPV4
int type, // SOCK_STREAM for TCP or SOCK_DGRAM for UDP
int protocol // IPPROTO_TCP or IPPROTO_UDP
);
// flow: server: socket()/WSASocket() -> bind() -> listen() -> accept()/WSAAccept()
// client: socket()/WSASocket() -> address -> connect()/WSAConnect()
// BIND()
int bind(
SOCKET s, // socket
const struct sockaddr FAR * name, // socket address
int namelen // socket address len
);
// example
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));
// example end
// LISTEN()
int listen(
SOCKET s, // socket
int backlog // the maximum queue length for pending connections
);
// ACCEPT()
SOCKET accept( // return new socket
SOCKET s, // listening socket
struct sockaddr FAR * addr, // client address
int FAR * addrlen // client address len
);
// CONNECT()
int connect(
SOCKET s, // client socket
const struct sockaddr FAR * name, // service address
int namelen // service address len
);
// --------------------------connect-oriented example--------------------------------------- //
// service.c
#include < winsock2.h >
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);
// 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
// want to listen for connections on all interfaces using port
// 5150. Notice how we convert the Port variable from host byte
// order to network byte order.
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));
// Listen for client connections. We used a backlog of 5, which
// is normal for many applications.
listen(ListeningSocket, 5);
// 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. We will
// describe how to send and receive data later in the chapter.
// When you are finished sending and receiving data on the
// NewConnection socket and are finished accepting new connections
// on ListeningSocket, you should close the sockets using the
// closesocket API. We will describe socket closure later in the
// chapter.
closesocket(NewConnection);
closesocket(ListeningSocket);
// When your application is finished handling the connections,
// call WSACleanup.
WSACleanup();
}
// client.c
#include < winsock2.h >
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);
// Set up a SOCKADDR_IN structure that will be used to connect
// to a listening server on port 5150. For demonstration
// purposes, let's assume our server's IP address is 136.149.3.29.
// Obviously, you will want to prompt the user for an IP address
// and fill in this field with the user's data.
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
// later in the chapter.
// When you are finished sending and receiving data on socket s,
// you should close the socket using the closesocket API. We will
// describe socket closure later in the chapter.
closesocket(s);
// When your application is finished handling the connection, call
// WSACleanup.
WSACleanup();
}
// --------------------------connect-oriented example ended--------------------------------- //
int send( // return: number of bytes sent, or SOCKET_ERROR
SOCKET s,
const char FAR * buf,
int len,
int flags /**/ /*0
MSG_DONTROUTE not to route the packet
MSG_OOB urgent msg, not used
*/
);
int WSASend(
SOCKET s,
LPWSABUF lpBuffers, // a pointer to one or more WSABUF structures
DWORD dwBufferCount, // count
LPDWORD lpNumberOfBytesSent, // bytes sent
DWORD dwFlags,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);
int recv(
SOCKET s,
char FAR * buf, // when buf<datagram/message(UDP),WASEMSGSIZE; not for TCP stream
int len,
int flags /**/ /*0 no special actions
MSG_PEEK copy, not delete from sys bufs, is bad
or MSG_OOB
*/
);
int WSARecv(
SOCKET s,
LPWSABUF lpBuffers,
DWORD dwBufferCount,
LPDWORD lpNumberOfBytesRecvd,
LPDWORD lpFlags, // MSG_PEEK, MSG_OOB, or MSG_PARTIAL
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);
// Stream Protocols send and recieve:
// note: within stream protocol you can 随便发送接收多少,不会超出范围
// send
char sendbuff[ 2048 ];
int nBytes = 2048 ,
nLeft,
idx;
// Fill sendbuff with 2048 bytes of data
// Assume s is a valid, connected stream socket
nLeft = nBytes;
idx = 0 ;
while (nLeft > 0 )
{
ret = send(s, &sendbuff[idx], nLeft, 0);
if (ret == SOCKET_ERROR)
{
// Error
}
nLeft -= ret;
idx += ret;
}
// recieve
char recvbuff[ 1024 ];
int ret,
nLeft,
idx;
nLeft = 512 ;
idx = 0 ;
while (nLeft > 0 )
{
ret = recv(s, &recvbuff[idx], nLeft, 0);
if (ret == SOCKET_ERROR)
{
// Error
}
idx += ret;
nLeft -= ret;
}
// Stream Protocols send and recieve ended
// shutdown is only meaningful for stream protocol
int shutdown(
SOCKET s,
int how // SD_RECEIVE, SD_SEND, or SD_BOTH. 即禁用什么
);
int closesocket (SOCKET s);
WORD wVersionRequested, // MAKEWORD(x, y), x=>minor version, y=>major version
LPWSADATA lpWSAData // pointer to
);
typedef struct WSAData
{
WORD wVersion; //seted by WSAStartup
WORD wHighVersion; //
char szDescription[WSADESCRIPTION_LEN + 1]; //n't really useful
char szSystemStatus[WSASYS_STATUS_LEN + 1]; //n't really useful
unsigned short iMaxSockets; //Do not use. maximum number of concurrently open sockets.
unsigned short iMaxUdpDg; //Do not use. the maximum datagram size
char FAR * lpVendorInfo; //not used
} WSADATA, * LPWSADATA;
// skeleton Winsock application
#include < winsock2.h >
void main( void )
{
WSADATA wsaData;
// Initialize Winsock version 2.2
if ((Ret = WSAStartup(MAKEWORD(2,2), &wsaData)) != 0)
{
// NOTE: Since Winsock failed to load we cannot use
// WSAGetLastError to determine the specific error for
// why it failed. Instead we can rely on the return
// status of WSAStartup.
printf("WSAStartup failed with error %d\n", Ret);
return;
}
// Setup Winsock communication code here
// When your application is finished call WSACleanup
if (WSACleanup() == SOCKET_ERROR)
{
printf("WSACleanup failed with error %d\n", WSAGetLastError());//flip side of which is WSASetLastError
}
}
// SOCKADDR_IN, when want to listen for incoming client requests
struct sockaddr_in
{
short sin_family; //must be AF_INET, for IP
u_short sin_port; //port
struct in_addr sin_addr; //4 byte
char sin_zero[8];//padding to make SOCKADDR_IN same size as SOCKADDR
} ;
// convert "*.*.*.*" to 32-bit unsigned long integer
unsigned long inet_addr(
const char FAR * cp
);
// ------------------------sin initialize - block start--------------------------- //
SOCKADDR_IN InternetAddr;
INT nPortId = 5150 ;
InternetAddr.sin_family = AF_INET;
// Convert the proposed dotted Internet address 136.149.3.29
// to a four-byte integer, and assign it to sin_addr
InternetAddr.sin_addr.s_addr = inet_addr( " 136.149.3.29 " );
// The nPortId variable is stored in host-byte order. Convert
// nPortId to network-byte order, and assign it to sin_port.
InternetAddr.sin_port = htons(nPortId);
// ------------------------sin initialize - block end--------------------------- //
// ------------------------convert functions - block start--------------------------- //
// host-byte => network-byte
u_long htonl(u_long hostlong);
int WSAHtonl(
SOCKET s,
u_long hostlong,
u_long FAR * lpnetlong
);
u_short htons(u_short hostshort);
int WSAHtons(
SOCKET s,
u_short hostshort,
u_short FAR * lpnetshort
);
// network-byte => host-byte
u_long ntohl(u_long netlong);
int WSANtohl(
SOCKET s,
u_long netlong,
u_long FAR * lphostlong
);
u_short ntohs(u_short netshort);
int WSANtohs(
SOCKET s,
u_short netshort,
u_short FAR * lphostshort
);
// ------------------------convert functions - block end--------------------------- //
SOCKET socket (
int af, // AF_INET for IPV4
int type, // SOCK_STREAM for TCP or SOCK_DGRAM for UDP
int protocol // IPPROTO_TCP or IPPROTO_UDP
);
// flow: server: socket()/WSASocket() -> bind() -> listen() -> accept()/WSAAccept()
// client: socket()/WSASocket() -> address -> connect()/WSAConnect()
// BIND()
int bind(
SOCKET s, // socket
const struct sockaddr FAR * name, // socket address
int namelen // socket address len
);
// example
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));
// example end
// LISTEN()
int listen(
SOCKET s, // socket
int backlog // the maximum queue length for pending connections
);
// ACCEPT()
SOCKET accept( // return new socket
SOCKET s, // listening socket
struct sockaddr FAR * addr, // client address
int FAR * addrlen // client address len
);
// CONNECT()
int connect(
SOCKET s, // client socket
const struct sockaddr FAR * name, // service address
int namelen // service address len
);
// --------------------------connect-oriented example--------------------------------------- //
// service.c
#include < winsock2.h >
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);
// 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
// want to listen for connections on all interfaces using port
// 5150. Notice how we convert the Port variable from host byte
// order to network byte order.
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));
// Listen for client connections. We used a backlog of 5, which
// is normal for many applications.
listen(ListeningSocket, 5);
// 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. We will
// describe how to send and receive data later in the chapter.
// When you are finished sending and receiving data on the
// NewConnection socket and are finished accepting new connections
// on ListeningSocket, you should close the sockets using the
// closesocket API. We will describe socket closure later in the
// chapter.
closesocket(NewConnection);
closesocket(ListeningSocket);
// When your application is finished handling the connections,
// call WSACleanup.
WSACleanup();
}
// client.c
#include < winsock2.h >
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);
// Set up a SOCKADDR_IN structure that will be used to connect
// to a listening server on port 5150. For demonstration
// purposes, let's assume our server's IP address is 136.149.3.29.
// Obviously, you will want to prompt the user for an IP address
// and fill in this field with the user's data.
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
// later in the chapter.
// When you are finished sending and receiving data on socket s,
// you should close the socket using the closesocket API. We will
// describe socket closure later in the chapter.
closesocket(s);
// When your application is finished handling the connection, call
// WSACleanup.
WSACleanup();
}
// --------------------------connect-oriented example ended--------------------------------- //
int send( // return: number of bytes sent, or SOCKET_ERROR
SOCKET s,
const char FAR * buf,
int len,
int flags /**/ /*0
MSG_DONTROUTE not to route the packet
MSG_OOB urgent msg, not used
*/
);
int WSASend(
SOCKET s,
LPWSABUF lpBuffers, // a pointer to one or more WSABUF structures
DWORD dwBufferCount, // count
LPDWORD lpNumberOfBytesSent, // bytes sent
DWORD dwFlags,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);
int recv(
SOCKET s,
char FAR * buf, // when buf<datagram/message(UDP),WASEMSGSIZE; not for TCP stream
int len,
int flags /**/ /*0 no special actions
MSG_PEEK copy, not delete from sys bufs, is bad
or MSG_OOB
*/
);
int WSARecv(
SOCKET s,
LPWSABUF lpBuffers,
DWORD dwBufferCount,
LPDWORD lpNumberOfBytesRecvd,
LPDWORD lpFlags, // MSG_PEEK, MSG_OOB, or MSG_PARTIAL
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);
// Stream Protocols send and recieve:
// note: within stream protocol you can 随便发送接收多少,不会超出范围
// send
char sendbuff[ 2048 ];
int nBytes = 2048 ,
nLeft,
idx;
// Fill sendbuff with 2048 bytes of data
// Assume s is a valid, connected stream socket
nLeft = nBytes;
idx = 0 ;
while (nLeft > 0 )
{
ret = send(s, &sendbuff[idx], nLeft, 0);
if (ret == SOCKET_ERROR)
{
// Error
}
nLeft -= ret;
idx += ret;
}
// recieve
char recvbuff[ 1024 ];
int ret,
nLeft,
idx;
nLeft = 512 ;
idx = 0 ;
while (nLeft > 0 )
{
ret = recv(s, &recvbuff[idx], nLeft, 0);
if (ret == SOCKET_ERROR)
{
// Error
}
idx += ret;
nLeft -= ret;
}
// Stream Protocols send and recieve ended
// shutdown is only meaningful for stream protocol
int shutdown(
SOCKET s,
int how // SD_RECEIVE, SD_SEND, or SD_BOTH. 即禁用什么
);
int closesocket (SOCKET s);