频道栏目
首页 > 系统 > win7激活工具 > 正文
Windows Socket API函数的用法及理解(代码实例)
2018-04-08 11:49:33      个评论    来源:Datura_Metel的博客  
收藏   我要投稿

Windows Socket API函数的用法及理解(代码实例)

#include "winsock2.h"
#pragma comment(lib, "ws2_32.lib")
#include "stdlib.h"

int main()
{
    WSADATA wsadata;
    if (WSAStartup(MAKEWORD(2, 2), &wsadata) != 0) 
    {
        printf("WSAStartup() 初始化失败!\n");
        return -1;
    }

    //socket()函数创建与指定的服务提供者绑定套接字
    //参数 af:指定协议的地址家族,通常使用AF_INET
    //参数 type:指定的套接字类型,SOCK_STREAM, SOCK_DGRAM, SOCK_RAW
    //参数 protocal:套接字使用的协议
    //socket() 函数执行成功,返回新Socket的句柄,调用失败返回INVALID_SOCKET
    //调用socket() 函数创建Socket后,该Socket就存在一个命名空间中,但并没有为其指定一个名称
    SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (s == INVALID_SOCKET)
    {
        printf("socket() 出错!\n");
    }

    //
    struct sockaddr_in addr;  //指定绑定的地址
    int addr_len = sizeof(struct sockaddr_in); //地址的长度
    int port = 9901;
    int errCode;
    
    //u_long htonl(u_long hostlong)
    //该函数将u_long类型的主机字节顺序格式IP地址转换为TCP/IP网络字节顺序格式
    //u_short htons(u_short hostshort)
    //该函数将u_short类型的主机字节顺序格式IP地址转换为TCP/IP网络字节顺序格式
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = htonl(INADDR_ANY);

    //bind() 函数可以将本地地址与一个Socket绑定在一起,执行成功返回0,调用失败返回SOCKET_ERROR
    //调用bind() 函数可以为未命名的的Socket 指定一个名称
    //名称由地址家族,主机地址,端口号3部分组成(当使用Internet地址家族)
    //下面的例子使用bind() 函数绑定TCP Socket 到本地地址的9901端口
    errCode = bind(s, (SOCKADDR*)&addr, addr_len);
    if (errCode == SOCKET_ERROR)
    {
        printf("bind() 出错\n");
        exit(1);
    }

    //listen()函数可以将套接字设置为监听接入的状态
    //参数 s:指定一个已经绑定但是尚未连接的套接字
    //参数 backlog:指定等待连接队列的最大长度
    //listen()函数执行成功返回0,调用失败返回SOCKET_ERROR
    errCode = listen(s, 3);
    if (errCode == SOCKET_ERROR)
    {
        printf("listen() 出错!\n");
        exit(1);
    }

    SOCKET sockAccept;  //执行accept() 函数后新建的用于实际通信的套接字
    struct sockaddr_in from;  //用于接受接入地址
    int len = sizeof(struct sockaddr_in);

    //使用accept() 函数在处于监听状态的套接字上接受接入请求
    //参数 s:通过调用listen() 函数设置为监听状态的套接字
    //参数 addr:输出参数,用于接受接入地址信息,这是一个可选参数,如果不关注地址,可以使用NULL
    //参数 addrlen:输出参数,指定接入地址的长度,这是一个可选参数
    //accept() 函数调用成功,返回一个新建的Socket句柄,该Socket用于实现服务器和客户端之间的通信,
    //如果函数调用失败,则返回INVALID_SOCKET
    sockAccept = accept(s, (struct sockaddr *)&sockAccept, &len);
    if (sockAccept == INVALID_SOCKET)
    {
        printf("accept() 出错!\n");
    }
    else
    {
        //char FAR * inet_ntoa(struct in_addr in)
        //该函数将in_addr结构体中的IP地址转换为点分法IP地址字符串
        //参数 in:是in_addr结构体类型,表示要进行转换的IP地址,返回结果是char *类型的IP地址
        printf("%s\n", inet_ntoa(from.sin_addr));  //打印接入地址
    }



    if (WSACleanup() == SOCKET_ERROR)
    {
        printf("WSACleanup() 出错!\n\n");
    }
    system("pause");
    return 0;
}
/*
#if !defined(MAKEWORD)
#define MAKEWORD(low,high) ((WORD)(((BYTE)(low)) | ((WORD)((BYTE)(high))) << 8))
#endif
#define SOCK_STREAM     1               // stream socket 
#define SOCK_DGRAM      2               // datagram socket 
#define SOCK_RAW        3               // raw-protocol interface 
#define SOCK_RDM        4                //reliably-delivered message 
#define SOCK_SEQPACKET  5                //sequenced packet stream 
#define AF_INET         2               // internetwork: UDP, TCP, etc.
#define INVALID_SOCKET  (SOCKET)(~0)
#define SOCKET_ERROR            (-1)
// IPv4 Socket address, Internet style
//

typedef struct sockaddr_in {

#if(_WIN32_WINNT < 0x0600)
short   sin_family;
#else //(_WIN32_WINNT < 0x0600)
ADDRESS_FAMILY sin_family;
#endif //(_WIN32_WINNT < 0x0600)

USHORT sin_port;
IN_ADDR sin_addr;
CHAR sin_zero[8];
} SOCKADDR_IN, *PSOCKADDR_IN;

// Structure used to store most addresses.
//
typedef struct sockaddr {

#if (_WIN32_WINNT < 0x0600)
u_short sa_family;
#else
ADDRESS_FAMILY sa_family;           // Address family.
#endif //(_WIN32_WINNT < 0x0600)

CHAR sa_data[14];                   // Up to 14 bytes of direct address.
} SOCKADDR, *PSOCKADDR, FAR *LPSOCKADDR;

#ifndef s_addr
#pragma once

//
// IPv4 Internet address
// This is an 'on-wire' format structure.
//
typedef struct in_addr {
union {
struct { UCHAR s_b1,s_b2,s_b3,s_b4; } S_un_b;
struct { USHORT s_w1,s_w2; } S_un_w;
ULONG S_addr;
} S_un;
#define s_addr  S_un.S_addr         //can be used for most tcp & ip code 
#define s_host  S_un.S_un_b.s_b2    // host on imp
#define s_net   S_un.S_un_b.s_b1    // network
#define s_imp   S_un.S_un_w.s_w2    // imp
#define s_impno S_un.S_un_b.s_b4    // imp #
#define s_lh    S_un.S_un_b.s_b3    // logical host
} IN_ADDR, *PIN_ADDR, FAR *LPIN_ADDR;

#endif
*/
点击复制链接 与好友分享!回本站首页
上一篇:Windows中如何杀死占用某个端口的进程?
下一篇:windows自带的客户端程序telnet使用介绍
相关文章
图文推荐
点击排行

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站