九零登录

[【通过】] 【已转正】UDP端口转发

[复制链接]
发表于 2016-7-22 11:08:49 | 显示全部楼层 |阅读模式
控制台应用程序。用法:P2P.exe  本地监听端口  服务器地址  服务器监听端口
要注意一点,程序使用多路复用进行数据接收与发送,会默认绑定本机6789端口(程序中可改),与服务器交换数据。不然select出错。编译软件:VS2008。
main.cpp

[C] 纯文本查看 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include <errno.h>
#include <signal.h>

#pragma comment(lib, "ws2_32.lib")

#define TIMEOUT 300    //select轮询时间
#define MAXSIZE 20480    //字符缓冲长度
#define HOSTLEN 40    //主机地址

struct transocket
{
        SOCKET fd1;    //用于监听的套接字
        SOCKET fd2;    //用于传输的套接字
        char host[HOSTLEN];    //转发给服务端地址
        int port;    //转发给服务端端口
};

int create_socket();    //创建套接字
int create_server(int sockfd, int port);    //将端口与套接字绑定,用于接收和发送数据
void transmitdata(LPVOID data);    //数据交换
void bind2conn(int port1, char *host, int port2);


int main(int argc, char* argv[])
{        if(argc != 4)
                return 0;

        char sConnectHost[HOSTLEN], sTransmitHost[HOSTLEN];
        int iConnectPort = 0, iTransmitPort = 0;

        memset(sConnectHost, 0, HOSTLEN);
        memset(sTransmitHost, 0, HOSTLEN);

        WSADATA wsaData;
        WSAStartup(MAKEWORD(2, 2), &wsaData);

        iConnectPort = atoi(argv[1]);
        strncpy_s(sTransmitHost, argv[2], HOSTLEN);
        iTransmitPort = atoi(argv[3]);
        bind2conn(iConnectPort, sTransmitHost, iTransmitPort);
        WSACleanup();
        return 0;
}

void bind2conn(int port1, char *host, int port2)
{
        SOCKET sockfd1, sockfd2;
        int size;
        char buffer[1024];

        HANDLE hThread = NULL;
        transocket sock;
        DWORD dwThreadID;

        if(port1 > 65535 || port1 < 1)
        {
                printf("[-] ConnectPort invalid.\r\n");
                return;
        }

        if(port2 > 65535 || port2 < 1)
        {
                printf("[-] TransmitPort invalid.\r\n");
                return;
        }

        memset(buffer, 0, 1024);

        if((sockfd1 = create_socket()) == INVALID_SOCKET) return;

        if(create_server(sockfd1, port1) == 0)
        {
                closesocket(sockfd1);
                return;
        }

        if((sockfd2 = create_socket()) == 0) return;
        
        if((create_server(sockfd2, 6789)) == 0)
        {
                closesocket(sockfd1);
                closesocket(sockfd2);
                return;
        }

        size = sizeof(struct sockaddr);

        while(1)
        {
                sock.fd1 = sockfd1;
                sock.fd2 = sockfd2;
                memcpy((char *)sock.host, host, HOSTLEN);
                sock.port = port2;

                hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)transmitdata, (LPVOID)&sock, 0, &dwThreadID);

                 if(hThread == NULL)
                {
                        TerminateThread(hThread, 0);
                        return ;
                }

                Sleep(10000);
        }

}
void transmitdata(LPVOID data)
{
        SOCKET fd1, fd2;
        transocket *sock;
        struct timeval timeset;
        fd_set readfd,writefd;
        int result,i=0;
        char read_in1[MAXSIZE],send_out1[MAXSIZE];
        char read_in2[MAXSIZE],send_out2[MAXSIZE];
        int read1=0,totalread1=0,send1=0;
        int read2=0,totalread2=0,send2=0;
        int sendcount1,sendcount2;
        int maxfd;
        struct sockaddr_in client1,client2;
        int structsize1,structsize2;
        char host1[20],host2[20];
        int port1=0,port2=0;
        char tmpbuf[100];

        sock = (transocket *)data;
        fd1 = sock->fd1;
        fd2 = sock->fd2;
        client2.sin_family = AF_INET;
        client2.sin_addr.S_un.S_addr = inet_addr(sock->host);
        client2.sin_port = htons(sock->port);

        memset(host1, 0, 20);
        memset(host2, 0, 20);
        memset(tmpbuf, 0, 100);

        structsize1=sizeof(struct sockaddr);
        structsize2=sizeof(struct sockaddr);

        maxfd = max(fd1, fd2) + 1;
        memset(read_in1,0,MAXSIZE);
        memset(read_in2,0,MAXSIZE);
        memset(send_out1,0,MAXSIZE);
        memset(send_out2,0,MAXSIZE);

        timeset.tv_sec = TIMEOUT;
        timeset.tv_usec = 0;

        while(1)
        {
                FD_ZERO(&readfd);
                FD_ZERO(&writefd);

                FD_SET((UINT)fd1, &readfd);
                FD_SET((UINT)fd1, &writefd);
                FD_SET((UINT)fd2, &readfd);
                FD_SET((UINT)fd2, &writefd);

                result = select(maxfd, &readfd, &writefd, NULL, ×et);
                if((result<0) && (errno!=EINTR))
                {
                        printf("[-] Select error.\r\n");
                        break;
                }
                else if(result==0)
                {
                        printf("[-] Socket time out.\r\n");
                        break;
                }

                 if(FD_ISSET(fd1, &readfd))
                {
                        if(totalread1 < MAXSIZE)
                        {
                                read1 = recvfrom(fd1, read_in1, MAXSIZE - totalread1, 0, (sockaddr *)&client1, &structsize1);
                                if((read1 == SOCKET_ERROR) || (read1 == 0))
                                {
                                        printf("[-] Read fd1 data error,maybe close?\r\n");
                                        break;
                                }
                                memcpy(send_out1 + totalread1, read_in1, read1);
                                printf(" Recv from client %5d bytes.\r\n", read1);
                                totalread1 += read1;
                                memset(read_in1, 0, MAXSIZE);
                        }
                }

                if(FD_ISSET(fd2, &writefd))
                {
                        int err = 0;
                        sendcount1 = 0;
                        while(totalread1 > 0)
                        {
                                send1 = sendto(fd2, send_out1 + sendcount1, totalread1, 0, (sockaddr *)&client2, structsize1);
                                if(send1 == 0) break;
                                if((send1 < 0) && (errno != EINTR))
                                {
                                        printf("[-] Send to fd2 unknow error.\r\n");
                                        err = 1;
                                        break;
                                }

                                if((send1 < 0) && (errno == ENOSPC)) break;
                                sendcount1 += send1;
                                totalread1 -= send1;

                                printf(" Send to server %5d bytes.\r\n", send1);
                        }

                        if(err == 1) break;
                        if((totalread1 > 0) && (sendcount1 > 0))
                        {
                                memcpy(send_out1,send_out1+sendcount1,totalread1);
                                memset(send_out1+totalread1,0,MAXSIZE-totalread1);
                        }
                        else
                                memset(send_out1,0,MAXSIZE);
                }

                if(FD_ISSET(fd2, &readfd))
                {
                        if(totalread2 < MAXSIZE)
                        {
                                read2 = recvfrom(fd2, read_in2, MAXSIZE - totalread2, 0, (sockaddr*)&client2, &structsize2);
                                if(read2==0)break;
                                if((read2<0) && (errno!=EINTR))
                                {
                                        printf("[-] Read fd2 data error,maybe close?\r\n\r\n");
                                        break;
                                }

                                memcpy(send_out2+totalread2,read_in2,read2);
                                printf(" Recv from server %5d bytes.\r\n", read2);
                                totalread2+=read2;
                                memset(read_in2,0,MAXSIZE);
                        }
                }

                if(FD_ISSET(fd1, &writefd))
                {
                        int err2=0;
                        sendcount2=0;
                        while(totalread2>0)
                        {

                                send2 = sendto(fd1, send_out2+sendcount2, totalread2, 0, (sockaddr*)&client1, structsize1);
                                if(send2==0) break;
                                if((send2<0) && (errno!=EINTR))
                                {
                                        printf("[-] Send to fd1 unknow error.\r\n");
                                        err2=1;
                                        break;
                                }
                                if((send2<0) && (errno==ENOSPC)) break;
                                sendcount2+=send2;
                                totalread2-=send2;

                                printf(" Send to client%5d bytes.\r\n", send2);
                        }
                        if(err2==1) break;
                        if((totalread2>0) && (sendcount2 > 0))
                        {
                                memcpy(send_out2, send_out2+sendcount2, totalread2);
                                memset(send_out2+totalread2, 0, MAXSIZE-totalread2);
                        }
                        else
                                memset(send_out2,0,MAXSIZE);
                        Sleep(5);
                }
        }
        closesocket(fd1);
        closesocket(fd2);

        printf("\r\n[+] OK! I Closed The Two Socket.\r\n"); 
}

int create_socket()
{
        int sockfd;
        sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
        if(sockfd < 0)
        {
                printf("[-] Create socket error.\r\n");
        }
        return sockfd;
}
int create_server(int sockfd, int port)
{
        struct sockaddr_in srvaddr;
        int on = 1;

        memset(&srvaddr, 0, sizeof(struct sockaddr));

        srvaddr.sin_port = htons(port);
        srvaddr.sin_family = AF_INET;
        srvaddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);

        if(bind(sockfd, (struct sockaddr *)&srvaddr, sizeof(struct sockaddr)) < 0)
        {
                printf("[-] Socket bind %d port error.\r\n", port);
                return 0;
        }
        return 1;
}

========================
2位90Sec Team成员同意,转正成功。
                  管理05


单选投票, 共有 8 人参与投票

投票已经结束

100.00% (8)
0.00% (0)
您所在的用户组没有投票权限

评分

参与人数 2酒票 +6 收起 理由
管理05 + 5 欢迎加入90!
uncia + 1 你是可以的,请继续完善bug

查看全部评分

发表于 2016-7-22 11:35:56 | 显示全部楼层
@Arlen
是楼主自己写的脚本吗
 楼主| 发表于 2016-7-22 11:38:42 | 显示全部楼层
本帖最后由 Arlen 于 2016-7-22 11:40 编辑
接地气 发表于 2016-7-22 11:35
@Arlen
是楼主自己写的脚本吗

是啊。网上找到的都是TCP协议端口转发的。这个程序还有点bug,正在努力修正
发表于 2016-7-22 12:12:19 | 显示全部楼层
虽然好,但是不太实用,如果udp能弹出来,tcp应该也可以吧?而且udp还卡,特容易丢包。不过使用udp不容易被发现是真的。
 楼主| 发表于 2016-7-22 12:32:03 | 显示全部楼层
anony 发表于 2016-7-22 12:12
虽然好,但是不太实用,如果udp能弹出来,tcp应该也可以吧?而且udp还卡,特容易丢包。不过使用udp不容易被 ...

网络差不多的情况下,丢包也没有那么严重啦
发表于 2016-7-22 13:41:07 | 显示全部楼层
楼主来份编译好的
 楼主| 发表于 2016-7-22 14:37:11 | 显示全部楼层
pony 发表于 2016-7-22 13:41
楼主来份编译好的

这个可以直接编译的。用VS2008。

九零

GMT+8, 2026-10-22 12:53

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表