//************************************************************************************
// 功能:监听本地1080端口数据,进行代理转发
// 服务端:可采用squid进行HTTP代理
// Socket Transmit to Socket
//
//************************************************************************************
// stdafx.h : 定义头文件。
//
#include "stdafx.h"
#include
#include
#include
#include
#include
#pragma comment(lib,"WS2_32")
#define TIMEOUT 300
#define MAXSIZE 20480
#define HOSTLEN 40
#define CONNECTNUM 5
#define PROXY_HOST "192.168.5.136"
#define PROXY_PORT 3128
// proxy.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
struct transocket
{
SOCKET fd1;
SOCKET fd2;
};
//************************************************************************************
//
// Socket Transmit to Socket
//
//************************************************************************************
DWORD WINAPI 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;
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;
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, &writefd);
FD_SET((UINT)fd2, &readfd);
result = select(maxfd, &readfd, &writefd, NULL, ×et);
if ((result<0) && (errno != EINTR))
{
break;
}
else if (result == 0)
{
break;
}
if (FD_ISSET(fd1, &readfd))
{
/* must < MAXSIZE-totalread1, otherwise send_out1 will flow */
if (totalread1 < MAXSIZE
) {
read1 = recv(fd1, read_in1, MAXSIZE - totalread1, 0);
if ((read1 == SOCKET_ERROR) || (read1 == 0))
{
break;
}
memcpy(send_out1 + totalread1, read_in1, read1);
totalread1 += read1;
memset(read_in1, 0, MAXSIZE);
}
}
if (FD_ISSET(fd2, &writefd))
{
int err = 0;
sendcount1 = 0;
while (totalread1>0)
{
send1 = send(fd2, send_out1 + sendcount1, totalread1, 0);
if (send1 == 0)break;
if ((send1<0) && (errno != EINTR))
{
err = 1;
break;
}
if ((send1<0) && (errno == ENOSPC)) break;
sendcount1 += send1;
totalread1 -= 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 = recv(fd2, read_in2, MAXSIZE - totalread2, 0);
if (read2 == 0)break;
if ((read2<0) && (errno != EINTR))
{
break;
}
memcpy(send_out2 + totalread2, read_in2, read2);
totalread2 += read2;
memset(read_in2, 0, MAXSIZE);
}
}
if (FD_ISSET(fd1, &writefd))
{
int err2 = 0;
sendcount2 = 0;
while (totalread2>0)
{
send2 = send(fd1, send_out2 + sendcount2, totalread2, 0);
if (send2 == 0)break;
if ((send2<0) && (errno != EINTR))
{
err2 = 1;
break;
}
if ((send2<0) && (errno == ENOSPC)) break;
sendcount2 += send2;
totalread2 -= 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);
}
}
closesocket(fd1);
closesocket(fd2);
return 0;
}
DWORD WINAPI ThreadNewConnect(LPVOID lpParam)
{
transocket sock;
sock.fd1 = *(SOCKET *)lpParam;
//////////////////连接远程服务器////////////////////////
sock.fd2 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock.fd2 == INVALID_SOCKET)
{
printf("远程 socket 错误代码:%d\n", WSAGetLastError());
closesocket(sock.fd1);
return 0;
}
sockaddr_in conn_sin;
conn_sin.sin_family = AF_INET;
InetPton(AF_INET, TEXT(PROXY_HOST), &conn_sin.sin_addr.s_addr);
conn_sin.sin_port = htons(PROXY_PORT);
if (connect(sock.fd2, (SOCKADDR*)&conn_sin, sizeof(conn_sin)) == SOCKET_ERROR)
{
printf("连接代理服务器 错误代码:%d\n", WSAGetLastError());
closesocket(sock.fd1);
closesocket(sock.fd2);
return 0;
}
////////////////////////////////////////////////////////
DWORD dwThreadID;
HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)transmitdata, (LPVOID)&sock, 0, &dwThreadID);
struct sockaddr_in local_sin;
int structsize1 = sizeof(struct sockaddr);
getpeername(sock.fd1, (struct sockaddr *)&local_sin, &structsize1);
char localip[20], connip[20];
inet_ntop(AF_INET, (void*)&local_sin.sin_addr, localip, 16);
inet_ntop(AF_INET, (void*)&conn_sin.sin_addr, connip, 16);
printf("开始数据双向传送%s:%d <-----> %s:%d\n", localip, local_sin.sin_port, connip , conn_sin.sin_port);
WaitForSingleObject(hThread , -1);
printf("----------------------------------------\n\n线程结束 线程id:%d\n\n----------------------------------------\n\n", GetCurrentThreadId());
return 0;
}
int main()
{
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR)
{
printf("WSAStartup 错误代码:%d\n", WSAGetLastError());
WSACleanup();
return 0;
}
SOCKET hLocalSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (hLocalSocket == INVALID_SOCKET)
{
printf("本地socket 错误代码:%d\n", WSAGetLastError());
WSACleanup();
return 0;
}
sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(1080);
sin.sin_addr.S_un.S_addr = INADDR_ANY;
if (bind(hLocalSocket, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR)
{
printf("绑定本地端口 错误代码:%d\n", WSAGetLastError());
WSACleanup();
return 0;
}
if (listen(hLocalSocket, 1024) == SOCKET_ERROR)
{
printf("监听本地端口 错误代码:%d\n", WSAGetLastError());
WSACleanup();
return 0;
}
sockaddr_in remoteAddr;
int nAddrLen = sizeof(remoteAddr);
while (1)
{
SOCKET Srev1 = accept(hLocalSocket, (SOCKADDR *)&remoteAddr, &nAddrLen);
DWORD dwThreadId = 0;
HANDLE hThread = CreateThread(NULL, 0, ThreadNewConnect, (void*)&Srev1, 0, &dwThreadId);
printf("----------------------------------------\n\n新连接,线程ID:%d\n\n----------------------------------------\n\n", dwThreadId);
}
closesocket(hLocalSocket);
WSACleanup();
}