zoukankan      html  css  js  c++  java
  • WinSocket编程笔记(二)

    bind 绑定函数(服务器端专属函数,有三种结构体,这里只介绍一种)

    通常,在一个SOCK_STREAM套接字接收连接之前,必须通过bind()函数用本地地址为套接字命名

    sockaddr_in 结构体

    定义内容:

    sin_family 地址族: 与socket()的第一个参数相同含义,必须为 AF_INET
    sin_port 端口号
    sin_addr IPv4 地址
    sin_zero[8] 对齐

    实例定义:

    SOCKET ListenSocket = socket(AF_INET,SOCK_STREAM,0);
    sockaddr_in sockAddr;//结构体名称为sockAddr sockAddr.sin_family = AF_INET; sockAddr.sin_port = htons(8888);//默认为htons(PORT)

    sockAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");//默认为INADDR_ANY
    int n;//这里定义n是为了判断是否出错,可直接调用bind(),不用n=bind()

     n=bind(ListenSocket,(LPSOCKADDR)&sockAddr,sizeof(sockAddr));
     if(n==SOCKET_ERROR){
     cout<<"false"<<endl;
     return -1;
     }
     else{
     cout<<"端口绑定成功:"<<PORT<<endl;
     }

     注:为了简化编程一般将IP地址设置为INADDR_ANY,如果需要使用特定的IP地址则需要使用inet_addr 和inet_ntoa完成字符串和in_addr结构体的互换

    listen 监听函数

    函数原型:

    int listen(int sockfd/*已绑定但未监听的套接字*/, int backlog/*挂起连接队列的最大长度*/)

    定义实例:

    int listenStatus = listen(mySocket,10);//listen的是bind的socket名
    if(listenStatus == SOCKET_ERROR){
        cout<<"listen error";
        ...
        WSACleanup();
    }

    accept 接收连接请求(只存在服务器端,与客户端的connect一起使用)

    函数原型:

    SOCKET accept(
    
           SOCKET s,
    
           struct sockaddr FAR *addr,
    
           int FAR *addrlen
    
    );

    定义实例:

    listen(Socket, 20); 
    SOCKET serverocket;//新建socket
    SOCKADDR clntAddr; //新建结构体
    int nSize = sizeof(SOCKADDR); //结构体长度
    cout << "Wait connection" << endl;
    serverocket = accept(Socket/*listen的第一个参数名*/, (SOCKADDR*)&clntAddr/*结构体*/, &nSize/*结构体长度*/);

    connect 请求连接函数(客户端函数,和accept一起使用)

    客户端请求与服务器端建立连接

    • socket 若未绑定, 操作系统赋值绑定
    • addr 服务器端的地址结构
    • addrlen 服务器端地址长度
    • 返回值
      • 成功: 返回 0
      • 失败: 返回 SOCKET_ERROR

    函数原型:

    int connect(SOCKET s,const struct sockaddr *name,int namelen);
    //说明:第一个参数是套接字,
    //第二个是包含地址信息的sockaddr_in结构体,
    //第三个 是sockaddr_in结构体长度;
    
    //返回值: 正常返回0, 错误返回SOCKET_ERR,也就是-1,

    定义实例:

    sockaddr_in server;
            server.sin_family = AF_INET;
            server.sin_port = htons(8828);
            server.sin_addr.s_addr = inet_addr("127.0.0.1");
            if (connect(cnetsocket,(sockaddr*)&server,sizeof(server)) == SOCKET_ERROR)
            {
                break;
            }

    send 发送数据函数

    函数原型:

    int send(SOCKET S, const char *buf , int len, int flags)
    • 已连接的 socket
    • buf 待发送缓冲区
    • len 待发送内容长度
    • flags 选项, 一般为0

    定义实例:

    char buff[1024] = {"abcdefghijklmnopqrstuvwxyz"};
    
    int sent = 0;//已发送
    
    int total_size = sizeof(buff);
    
    sent = send(sock, buff+sent, total_size - sent, 0);

     

    recv 接收数据函数

    在已建立连接的 socket 上接收数据

    函数原型:

    int recv( SOCKET s,char* buf,int len,int flags);   
    • 已连接的 socket
    • buf 接受缓冲区
    • len 缓冲区长度
    • flags 选项, 一般为 0
        返回值
        • 成功: 返回实际接收的字节数
        • 连接已终止: 0
        • 失败: 返回 SOCKET_ERROR

    定义实例:

    char buffer[BUFFER_SIZE];
    memset(buffer, 0, BUFFER_SIZE);//这一步是初始化,不一定需要 n
    = recv(clntSocket/*注意这里的socket名称是定义的accept socket*/, buffer, BUFFER_SIZE, 0)

    实战(以之前内容为基础,编写回射程序,且服务器端能打印客户端的ip和端口)

    注:exe程序执行成功后自动退出,请在编译器里调试查看结果

    服务器:

    #include <iostream>
    #include <stdio.h>
    #include <winsock2.h>
    #pragma comment(lib,"ws2_32.lib")
    using namespace std;
    #define BUF_SIZE 100
    const int PORT = 8000;
    int main()
    {
        WORD sockVersion = MAKEWORD(2, 2);
    
        WSADATA data;
    
        if (WSAStartup(sockVersion, &data) != 0)
    
        {
    
            return 1;
    
        }
        SOCKET serverSocket = socket(AF_INET, SOCK_STREAM,0);
            if (serverSocket == INVALID_SOCKET){
                cout << "Socket error" << endl;}
        SOCKADDR_IN ListenAddr;
        ListenAddr.sin_family=AF_INET;
        ListenAddr.sin_addr.S_un.S_addr=INADDR_ANY;
        ListenAddr.sin_port=htons(PORT);
    //绑定socket
        int n;
        n=bind(serverSocket,(LPSOCKADDR)&ListenAddr,sizeof(ListenAddr));
        if(n==SOCKET_ERROR)
            {
                return false;
            }
        else{
        cout<<"端口绑定成功:"<<PORT<<endl;
        }
    //监听端口
        listen(serverSocket,20);
        struct sockaddr_in addrClient;
        int len = sizeof(struct sockaddr_in);
    //accept
        int sockConn = accept(serverSocket, (struct sockaddr *)&addrClient, &len);
        cout<<"ip="<<inet_ntoa(addrClient.sin_addr)<<endl;
        cout<<"port="<<ntohs(addrClient.sin_port)<<endl;
    //recv
        char buffer[BUF_SIZE];
        int m=recv(sockConn, buffer, BUF_SIZE, 0);
        if(m==SOCKET_ERROR)
            {
               return false;
            }
    //send
        send(sockConn,buffer,m,0);
    //closesocket
        closesocket(sockConn);
        closesocket(serverSocket);
    
        return 0;
    }

    客户端:

    #include <iostream>
    #include <stdio.h>
    #include <winsock2.h>
    #pragma comment(lib,"ws2_32.lib")
    using namespace std;
    #define BUF_SIZE 100

    int main() { WORD sockVersion = MAKEWORD(2, 2); WSADATA data; if (WSAStartup(sockVersion, &data) != 0) { return 1; } SOCKET clientSocket = socket(AF_INET, SOCK_STREAM,0); if (clientSocket == INVALID_SOCKET){ cout << "Socket error" << endl;} SOCKADDR_IN ListenAddr; ListenAddr.sin_family=AF_INET; ListenAddr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");; ListenAddr.sin_port=htons(PORT); //connect int ret=0; ret=connect(clientSocket,(sockaddr*)&ListenAddr, sizeof(struct sockaddr_in)); //send char buffer[BUF_SIZE] = {"569"}; send(clientSocket, buffer, BUF_SIZE, 0); //recv char buffRecv[BUF_SIZE]={0}; recv(clientSocket,buffRecv,BUF_SIZE,0); cout<<"返回数据:"<<buffRecv<<endl; //closesocket closesocket(clientSocket); return 0; }

    结果:客户端接收到自己发送给服务器的信息,并打印出来

    (待续)


    Reference

    https://www.cnblogs.com/quehualin/p/9334030.html

    https://blog.csdn.net/guothin/article/details/80635400

    http://c.biancheng.net/cpp/html/3038.html

    [Sign]做不出ctf题的时候很痛苦,你只能眼睁睁看着其他人领先你
  • 相关阅读:
    css盒子模型
    怎么查看浏览器内核以及浏览器版本
    matlab 读取文件(mat)存储为json文件
    js的闭包
    听别人报告
    关于windows下 python3安装 cython的说明
    python某个module使用了相对引用,同时其__name__又是__main__导致的错误
    python编程指南
    javacc在stanfordnlp中的应用
    hystrix熔断机制修改配置
  • 原文地址:https://www.cnblogs.com/echoDetected/p/12653768.html
Copyright © 2011-2022 走看看