Winsock基础篇(未完待续)

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 ;

=  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);

你可能感兴趣的:(Winsock基础篇(未完待续))