zoukankan      html  css  js  c++  java
  • c++ TCP 获取客户端IP

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<errno.h>
    #include<sys/types.h>
    #include<sys/socket.h>
    #include<netinet/in.h>


    #define MAXLINE 4096


    int main(int argc, char** argv)
    {
        int    listenfd, connfd;
        struct sockaddr_in     servaddr,caddr;
        char    buff[4096];
        int     n;


        if( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1 ){
        printf("create socket error: %s(errno: %d) ",strerror(errno),errno);
        exit(0);
        }


        memset(&servaddr, 0, sizeof(servaddr));
        memset(&caddr,0,sizeof(caddr));
        servaddr.sin_family = AF_INET;
        servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
        servaddr.sin_port = htons(6666);


        
        if( bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1){
        printf("bind socket error: %s(errno: %d) ",strerror(errno),errno);
        exit(0);
        }


        if( listen(listenfd, 10) == -1){
        printf("listen socket error: %s(errno: %d) ",strerror(errno),errno);
        exit(0);
        }


        printf("======waiting for client's request====== ");
        while(1){
    socklen_t length = sizeof(caddr);
        if( (connfd = accept(listenfd, (struct sockaddr*)&caddr,&length)) == -1){
            printf("accept socket error: %s(errno: %d)",strerror(errno),errno);
            continue;
        }
        n = recv(connfd, buff, MAXLINE, 0);
        buff[n] = '';
        printf("recv msg from client: %s ",buff);
        printf("recv msg from %s:client: %s ", inet_ntoa(caddr.sin_addr),buff);
        close(connfd);
        }


        close(listenfd);
    }

    客户端:原文未动

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<errno.h>
    #include<sys/types.h>
    #include<sys/socket.h>
    #include<netinet/in.h>


    #define MAXLINE 4096


    int main(int argc, char** argv)
    {
        int    sockfd, n;
        char    recvline[4096], sendline[4096];
        struct sockaddr_in    servaddr;


        if( argc != 2){
        printf("usage: ./client <ipaddress> ");
        exit(0);
        }


        if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
        printf("create socket error: %s(errno: %d) ", strerror(errno),errno);
        exit(0);
        }


        memset(&servaddr, 0, sizeof(servaddr));
        servaddr.sin_family = AF_INET;
        servaddr.sin_port = htons(6666);
        if( inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0){
        printf("inet_pton error for %s ",argv[1]);
        exit(0);
        }


        if( connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0){
        printf("connect error: %s(errno: %d) ",strerror(errno),errno);
        exit(0);
        }


        printf("send msg to server: ");
        fgets(sendline, 4096, stdin);
        if( send(sockfd, sendline, strlen(sendline), 0) < 0)
        {
        printf("send msg error: %s(errno: %d) ", strerror(errno), errno);
        exit(0);
        }


        close(sockfd);
        exit(0);
    }

    ======================================================================================

    各个函数介绍:

    socket,原型:

    int socket(int domain, int type, int protocol);

    选择协议域(ipv4 ipv6),socket类型(流 其他),协议(tcp udp)

    通过该操作 得到一个文件描述符

    将文件描述符和监听端口绑定

    bing(int sockfd, const struct sockaddr *addr, socklen_t addrlen)

    我们是是网络socket,所以要强转一下 ,两者区别:

    struct sockaddr是通用的套接字地址,而struct sockaddr_in则是internet环境下套接字的地址形式

    调用例子:

    bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr))

    绑定之后,便是listen,accept

    int listen(int sockfd, int backlog);
    int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

    listen定义监听的最大连接数

    accept将服务器socket与客户端的网络信息结合在一起,返回后续通讯达客户端句柄

    客户端,先调用socket,获取文件句柄,然后将服务器参数和句柄绑定int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);  然后就可以愉快通讯了。注意有个网络字节序和主机字节序

    网络是大端~~

    //======================================================================================================================

        头文件
        windows下:
        #include <WS2tcpip.h>
        linux下:
        #include <sys/socket.h>
        #include <netinet/in.h>
        #include<arpa/inet.h>
        inet_pton函数
        将点分十进制串转换成网络字节序二进制值,此函数对IPv4地址和IPv6地址都能处理。
        第一个参数可以是AF_INET或AF_INET6:
        第二个参数是一个指向点分十进制串的指针:
        第三个参数是一个指向转换后的网络字节序的二进制值的指针。
        inet_ntop函数
        和inet_pton函数正好相反,inet_ntop函数是将网络字节序二进制值转换成点分十进制串。
        第一个参数可以是AF_INET或AF_INET6:
        第二个参数是一个指向网络字节序的二进制值的指针;
        第三个参数是一个指向转换后的点分十进制串的指针;
        第四个参数是目标的大小,以免函数溢出其调用者的缓冲区。
        样例

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    int main (void)
    {
        char IPdotdec[20]; //存放点分十进制IP地址
        struct in_addr s; // IPv4地址结构体
        // 输入IP地址
        printf("Please input IP address: ");
        scanf("%s", IPdotdec);
        // 转换
        inet_pton(AF_INET, IPdotdec, (void *)&s);
        printf("inet_pton: 0x%x ", s.s_addr); // 注意得到的字节序
        // 反转换
        inet_ntop(AF_INET, (void *)&s, IPdotdec, 16);
        printf("inet_ntop: %s ", IPdotdec);
    }

  • 相关阅读:
    Jquery中的bind()方法绑定事件总结
    composer常用命令
    Activity四种启动模式
    谷歌搜索技巧
    关于Android studio Haxm加速器安装
    关于Ping和Tracert命令原理详解
    皮尔逊相关系数
    head标签
    wireshark抓包
    数据结构与算法自学系列之动态规划(一)
  • 原文地址:https://www.cnblogs.com/YZFHKMS-X/p/11761188.html
Copyright © 2011-2022 走看看