SOCKET双向数据传送代码

//************************************************************************************
// 功能:监听本地1080端口数据,进行代理转发
// 服务端:可采用squid进行HTTP代理
// Socket Transmit to Socket
//
//************************************************************************************

// stdafx.h : 定义头文件。
//

#include "stdafx.h"
#include <stdio.h>
#include <tchar.h>
#include <errno.h>
#include <winsock2.h>
#include <Ws2tcpip.h>
#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, &timeset);
		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();
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个简单的示例代码,用于在 Python 中使用 socket 进行数据传输: 服务器端代码: ```python import socket # 创建一个套接字对象 server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 绑定服务器的地址和端口 server_address = ('localhost', 8888) server_socket.bind(server_address) # 监听连接 server_socket.listen(1) print("等待客户端连接...") # 接受客户端连接 client_socket, client_address = server_socket.accept() print("客户端已连接:", client_address) # 接收客户端发送的数据 data = client_socket.recv(1024).decode() print("接收到的数据:", data) # 发送响应给客户端 response = "你好,我是服务器!" client_socket.send(response.encode()) # 关闭连接 client_socket.close() server_socket.close() ``` 客户端代码: ```python import socket # 创建一个套接字对象 client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 连接服务器 server_address = ('localhost', 8888) client_socket.connect(server_address) # 发送数据给服务器 message = "你好,我是客户端!" client_socket.send(message.encode()) # 接收服务器的响应 response = client_socket.recv(1024).decode() print("接收到的响应:", response) # 关闭连接 client_socket.close() ``` 这个示例展示了一个简单的客户端和服务器端的通信过程。在服务器端,我们首先创建一个套接字对象,绑定服务器的地址和端口,并开始监听连接。当客户端连接时,我们接收客户端发送的数据,然后发送响应给客户端,并关闭连接。 在客户端,我们创建一个套接字对象,连接服务器,并发送数据给服务器。然后,我们接收服务器的响应并打印出来,最后关闭连接。 你可以根据需要修改代码中的地址和端口,实现你自己的数据传输逻辑。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值