VC++之网络编程二 Socket

来源:互联网 发布:java中什么是对象 编辑:程序博客网 时间:2024/06/06 05:13

 二 socket

1.基于TCP(面向连接)的socket编程
服务器端程序:
1.创建套接字(socket).
2.将套接字绑定到一个本地地址和端口上(bind).
3.将套接字设为监听模式,准备接收客户请求(listen).
4.等待客户请求到来;当请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept).
5.用返回的套按字和客户端进行通信(send/recv).
6.返回,等待另一个客户请求.
7.关闭套按字.
客户端程序:
1.创建套接字(socket).
2.向服务器发出连接请求(connect).
3.和服务器端进行通信(send/recv).
4.关闭套接字.
2.基于UDP(面向无连接)的socket编程
服务器端:
1.创建套接字(socket).
2.将套接字绑定到一个本地地址和端口上(bind).
3.等待接收数据(recvfrom).
4.关闭套接字.
客户端:
1.创建套接字(socket).
2.向服务器发送数据(sendto).
3.关闭套接字.
3.项目实例
基于TCP(面向连接)的socket编程实例
1)相关函数
----------- 加载socket库 begin ---------------
WSAStartup---加载套接字库,套接字库的版本协商
MAKEWORD---通过同时指定值来创建一个WORD值
WSAData---用WSAStartup获取的版本信息填充在WSAData结构体中
LOBYTE---获取WORD低字节
HIBYTE---获取WORD高字节
WSACleanup---终止使用Winsock,释放资源
----------- 加载socket库 end ---------------
----------- 创建socket begin---------------
socket---创建一个套接字
----------- 创建socket end ---------------
----------- 绑定socket begin ---------------
bind---用一个套接字关联一个本地地址
sockaddr
sockaddr_in
in_addr
htonl---转换为一个u_long从主机字节序到TCP/IP网络字节序
htons---转换为一个u_short从主机字节序到TCP/IP网络字节序
----------- 绑定socket end ---------------
----------- socket监听 begin ---------------
listen---将套接字设定为监听模式,以监听连接请求
----------- socket监听 end ---------------
----------- 等待客户端连接请求 begin ---------------
accept---等待客户端连接请求
----------- 等待客户端连接请求 end ---------------
----------- 向客户端发送请求数据 begin ---------------
send---对连接的套接字发送请求的数据
inet_ntoa---接受in_addr类型参数,返回一个点分十进制格式的IP地址的字符串
----------- 向客户端发送请求数据 end ---------------
----------- 接收数据 begin ---------------
recv---从一个已连接的套接字或者一个绑定到未连接的套接字接收数据
----------- 接收数据 end ---------------
int WSAStartup(    //The WSAStartup function initiates use of the Winsock DLL by a process.
  WORD wVersionRequested,
  LPWSADATA lpWSAData   //[out] Pointer to the WSADATA structure that is to receive details of the Windows Sockets implementation. 
);
wVersionRequested:指定要加载的Winsock库的版本.高位字节指定库的副版本,低位字节指定主版本.可用MAKEWORD(x,y)(其中,x是低位字节(主版本),y是高位字节(副版本)(笔者注:原讲义在此处是:x是高位字节, y是低位字节,笔者参考MSDN Library-Visual Studio 2008 SP1 后作了修改))方便地获得wVersionRequested的正确值.
lpWSAData:是指向WSADATA结构的指针,WSADATA接收Windows Sockets 实现的详细信息.(WSAStartup用其加载的库版本有关的信息填在这个结构中)
成功调用WSAStartup后,在最后都对应一个WSACleanUp调用,以释放为应用程序分配的资源.
int  WSACleanup (void);   //The WSACleanup function terminates use of the Winsock 2 DLL (Ws2_32.dll).
WORD MAKEWORD(           //The MAKEWORD macro creates a WORD value by concatenating the specified values.
    BYTE bLow,                      //Specifies the low-order byte of the new value. 
    BYTE bHigh                      //Specifies the high-order byte of the new value. 
);
typedef struct WSAData {      //The WSADATA structure contains information about the Windows Sockets implementation.
  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; 
BYTE LOBYTE(    //The LOBYTE macro retrieves the low-order byte from the specified value. 
    WORD wValue
);
BYTE HIBYTE(    //The HIBYTE macro retrieves the high-order byte from the given 16-bit value. 
    WORD wValue
);
----------------------------------------------------
SOCKET socket(      //This function creates a socket that is bound to a specific service provider.
  int af,                    //[in] Address family specification. 
  int type,                //[in] Type specification for the new socket.  SOCK_STREAM | SOCK_DGRAM  | SOCK_RAW
  int protocol         //[in] Protocol to be used with the socket that is specific to the indicated address family.
);
the following list shows the possible value of protocol type :
IPPROTO_IP 
IPPROTO_IPV6 
IPPROTO_TCP 
IPPROTO_UDP 
SOL_SOCKET 
AF_INET             //The AF_INET address family is the address family for IPv4.
--------------------------------------
int bind(           //This function associates a local address with a socket.
  SOCKET s,
  const struct sockaddr FAR* name,
  int namelen
);
struct sockaddr {                     //The sockaddr structure varies depending on the protocol selected.
                                                   //Except for the sin*_family parameter, sockaddr contents are expressed in network byte order.
  u_short sa_family;
  char sa_data[14];
};
sockaddr 结构体是为所有的地址家族准备的,通常会随所使用的网络协议不同而不同,会用其它相关结构体来替换sockaddr这个结构体.
sa_data是一块内存区,用来放置与协议相关的具体地址信息.对不同的协议家族,必须用来同的结构体来替换sockaddr.在TCP/IP协议家族中,可以用sockaddr_in来替换sockaddr.
struct sockaddr_in {    //In the Internet address family, this structure is used by Windows Sockets to specify a local or remote endpoint
                                       // address to which to connect a socket. This is the form of the sockaddr structure specific to the Internet
                                       // address family and can be cast to sockaddr. 
        short   sin_family;     //Address family; must be AF_INET. 
        u_short sin_port;      //Internet Protocol (IP) port. 
        struct  in_addr sin_addr;      //IP address in network byte order. 
        char    sin_zero[8];        //Padding to make structure the same size as SOCKADDR. 
};
sockaddr_in如果调用成功,则返回0,调用不成功,则返回SOCKET_ERROR,可用WSAGetLastError函数取得错误信息.
typedef struct in_addr {    //The in_addr structure represents an IPv4 Internet address.
union {    
struct {   u_char s_b1,s_b2,s_b3,s_b4;    } S_un_b;      //An IPv4 address formatted as four u_chars.
struct {   u_short s_w1,s_w2;    } S_un_w;        //An IPv4 address formatted as two u_shorts.
u_long S_addr;        //An IPv4 address formatted as a u_long.
} S_un;
} IN_ADDR,  *PIN_ADDR,  FAR *LPIN_ADDR;
将IP地址指定为INADDR_ANY,允许一个独立应用接受发自多个接口的回应.
u_long htonl(      //The htonl function converts a u_long from host to TCP/IP network byte order (which is big endian).
  __in  u_long hostlong
);
u_short htons(    //The htons function converts a u_short from host to TCP/IP network byte order (which is big-endian).
  __in  u_short hostshort
);
--------------------------
int listen(    //This function places a socket at a state where it is listening for an incoming connection.
  SOCKET s,
  int backlog    //等待连接的最大长度
);
--------------------------
SOCKET accept(    //This function permits an incoming connection attempt on a socket.
  SOCKET s,
  struct sockaddr FAR* addr,   //save IP address and port of clients
  int FAR* addrlen
);
----------------------------
int send(    //This function sends data on a connected socket.
  SOCKET s,
  const char FAR* buf,
  int len,
  int flags
);
char* FAR inet_ntoa(    //The inet_ntoa function converts an (Ipv4) Internet network address
                                         // into a string in Internet standard dotted-decimal format.
  __in  struct   in_addr in
);
---------------------------------
int recv(    //The recv function receives data from a connected socket or a bound connectionless socket.
  __in   SOCKET s,
  __out  char* buf,
  __in   int len,
  __in   int flags
);