袜子5客户端用C [英] Socks 5 client in C

查看:138
本文介绍了袜子5客户端用C的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用C使用流式套接字写袜子5客户端。

I'd like to write socks 5 client using stream sockets in C.

下面是我的code:

/*
** client_socks.c -- a stream socket socks 5 client demo
*/

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

#include <arpa/inet.h>

#define PORT "9050" // the port client will be connecting to 

#define MAXDATASIZE 100 // max number of bytes we can get at once 

// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa)
{
    if (sa->sa_family == AF_INET) {
        return &(((struct sockaddr_in*)sa)->sin_addr);
    }

    return &(((struct sockaddr_in6*)sa)->sin6_addr);
}

int main(int argc, char *argv[])
{
    int sockfd, numbytes;  
    char buf[MAXDATASIZE];
    struct addrinfo hints, *servinfo, *p;
    int rv;
    char s[INET6_ADDRSTRLEN];

    if (argc != 2) {
        fprintf(stderr,"usage: client hostname\n");
        exit(1);
    }

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;

    if ((rv = getaddrinfo(argv[1], PORT, &hints, &servinfo)) != 0) {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
        return 1;
    }

    // loop through all the results and connect to the first we can
    for(p = servinfo; p != NULL; p = p->ai_next) {
        if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
            perror("client: socket");
            continue;
        }

        if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
            perror("client: connect");
            close(sockfd);
            continue;
        }

        break;
    }

    if (p == NULL) {
        fprintf(stderr, "client: failed to connect\n");
        return 2;
    }

    inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr), s, sizeof s);
    printf("client: connecting to %s\n", s);

    freeaddrinfo(servinfo); // all done with this structure

    /* Version 5, one method: no authentication */
    char buffer[256], *ptrBuff;
    ptrBuff = buffer;

    ptrBuff[0] = 5; // socks version
    ptrBuff[1] = 1;
    ptrBuff[2] = 0; // SOCKS_NOAUTH

    if (send(sockfd, ptrBuff, buffer-ptrBuff, 0) == -1)
                perror("send");

    if ((numbytes = recv(sockfd, buffer, MAXDATASIZE-1, 0)) == -1) {
        perror("recv");
        exit(1);
    }

    buffer[numbytes] = '\0';

    printf("client: received '%s'\n",buffer);

    close(sockfd);

    return 0;
}

但它不工作 - 它写:

But it's not working - It's writing:

client: connecting to 127.0.0.1 

和等待,这是所有

我还没有找到真正有用的例子如何做到这一点的C,所以我将不胜AP preciate任何帮助,您可以给我。

I have not found really useful examples how to do this in C, so I would greatly appreciate any help you can give me.

如何实现身份验证,也没有权威性的方法呢?

How to realize auth and no auth methods?

/*
** client_proxy.c -- a stream socket socks 5 client demo
*/

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

#include <arpa/inet.h>

#define PORT "9050" // the port client will be connecting to 

#define MAXDATASIZE 100 // max number of bytes we can get at once 

// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa)
{
    if (sa->sa_family == AF_INET) {
        return &(((struct sockaddr_in*)sa)->sin_addr);
    }

    return &(((struct sockaddr_in6*)sa)->sin6_addr);
}

int main(int argc, char *argv[])
{
    int sockfd, numbytes;  
    char buf[MAXDATASIZE];
    struct addrinfo hints, *servinfo, *p;
    int rv;
    char s[INET6_ADDRSTRLEN];

    if (argc != 2) {
        fprintf(stderr,"usage: client hostname\n");
        exit(1);
    }

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;

    if ((rv = getaddrinfo(argv[1], PORT, &hints, &servinfo)) != 0) {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
        return 1;
    }

    // loop through all the results and connect to the first we can
    for(p = servinfo; p != NULL; p = p->ai_next) {
        if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
            perror("client: socket");
            continue;
        }

        if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
            perror("client: connect");
            close(sockfd);
            continue;
        }

        break;
    }

    if (p == NULL) {
        fprintf(stderr, "client: failed to connect\n");
        return 2;
    }

    inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr), s, sizeof s);
    printf("client: connecting to %s\n", s);

    freeaddrinfo(servinfo); // all done with this structure

    /* Version 5, one method: no authentication */
    char buffer[256], *ptrBuff, bufferf[256];
    ptrBuff = buffer;

    *(ptrBuff++) = 5; // socks version
    *(ptrBuff++) = 2;
    *(ptrBuff++) = 0x00; // no auth 
    *(ptrBuff++) = 0x02; // user pass auth

    if (send(sockfd, ptrBuff, buffer-ptrBuff, 0) == -1)
                perror("send");

    printf("sent\n");

    if ((numbytes = recv(sockfd, bufferf, MAXDATASIZE-1, 0)) == -1) {
        perror("recv");
        exit(1);
    }

    printf("client: received '%d'\n", bufferf[1]);

    close(sockfd);

    return 0;
}

client: connecting to 127.0.0.1
sent
client: received '97

每次收到的号码是不同的,有什么不对?

Every time received number is different, what's wrong?

推荐答案

在这个code以深入了解:

Take a deeper look at this code:

char buffer[256], *ptrBuff;
ptrBuff = buffer;

ptrBuff[0] = 5; // socks version
ptrBuff[1] = 1;
ptrBuff[2] = 0; // SOCKS_NOAUTH

if (send(sockfd, ptrBuff, buffer-ptrBuff, 0) == -1)
            perror("send");

您逝去的发送功能 LEN 缓冲-ptrBuff 。但是,这些值(地址)是相同的地址,这样的结果是 0

You are passing to send function the len: buffer-ptrBuff. But those values (addresses) are the same address so the result is 0.

我猜,你想要做的是

char buffer[256], *ptrBuff;
ptrBuff = buffer;

*(ptrBuff++) = 5; // socks version
*(ptrBuff++) = 1;
*(ptrBuff++) = 0; // SOCKS_NOAUTH

if (send(sockfd, ptrBuff, buffer-ptrBuff, 0) == -1)
            perror("send");

在这种情况下, ptrBuff 值(地址指向),在每一个任务,所以当发送被称为<$递增C $ C> LEN (缓冲ptrBuff )将 3

In this case ptrBuff value (address pointed) is incremented at each assignment so when send is called len (buffer-ptrBuff) will be 3.

目前到底是什么,你看到的是正确的,由于事实,你什么都不发送到服务器端,并没有回答可以在客户端接收。因此,的recv 将永远等待的永远不会回答一个答案(阻塞模式)。

At the end what you are seeing is correct due to the fact that you are sending nothing to server side, and no answer can be received on client side. So recv waits forever (blocking mode) for an answer that will never answered.

这篇关于袜子5客户端用C的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆