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)\n",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)\n",strerror(errno),errno);
    exit(0);
    }


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


    printf("======waiting for client's request======\n");
    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] = '\0';
    printf("recv msg from client: %s\n",buff);
    printf("recv msg from %s:client: %s\n", 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>\n");
    exit(0);
    }


    if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
    printf("create socket error: %s(errno: %d)\n", 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\n",argv[1]);
    exit(0);
    }


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


    printf("send msg to server: \n");
    fgets(sendline, 4096, stdin);
    if( send(sockfd, sendline, strlen(sendline), 0) < 0)
    {
    printf("send msg error: %s(errno: %d)\n", 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\n", s.s_addr); // 注意得到的字節序
    // 反轉換
    inet_ntop(AF_INET, (void *)&s, IPdotdec, 16);
    printf("inet_ntop: %s\n", IPdotdec);
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM