Socket SDK (API) 编程

利用最基本的Socket API 编程


发送端:


#include <stdio.h>
#include <WinSock2.h>
#include <string.h>
#pragma comment( lib, "Ws2_32.lib" ) //要记得加这句话,不然编译错误,找不到库函数

void main()
{
	WSADATA wsaData;
	int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
	if ( iResult != NO_ERROR )
		printf("Error at WSAStartup()\n");
	SOCKET m_socket;//声明
	m_socket = socket(AF_INET, SOCK_STREAM ,IPPROTO_TCP);//初始化socket变量
	if ( m_socket == INVALID_SOCKET ) {
		printf( "Error at socket(): %ld\n", WSAGetLastError() );
		WSACleanup();
		return;	
	}

	sockaddr_in client;
	client.sin_family = AF_INET;
	client.sin_addr.s_addr = inet_addr("163.180.117.229");
	client.sin_port = htons(6000);
	if ( connect( m_socket, (SOCKADDR*) &client, sizeof(client) ) == SOCKET_ERROR) {//连接目标port,ip
		printf( "Failed to connect.\n" );
		WSACleanup();
		return;
	}

	int i; 
	char str[30] = "C://Sending_Packet//1";
	char str_end[5] = ".JPG";
	strcat(str,str_end);
	int PacketSize = 1024;//大文件分割传输,定义最小传输单元
	int PacketCount,LastDataPacket;
	int test;

	

	while(1)
	{
		test = 0;

		char* buffer;
		char* sendbuffer;
		char* lastbuffer;
		char buffer_count[10];
		char buffer_last[6];
		char temp[10];
		int lSize;
		int bytesSent;
		int bytesSent_count;
		int bytesSent_last;
		size_t result;
		//int temp;

		FILE* fp;

		if((fp = fopen(str,"rb")) == NULL)//定义文件流对象,rb是读二进制,wb是写二进制。
		{
			printf("cannot open file\n");
			break;
		}

		//get the length of pic file
		fseek(fp,0,SEEK_END);
		lSize = ftell(fp);
		rewind(fp);

		//allocate the memory for sending buffer
		buffer = (char*)malloc(sizeof(char)*lSize);
		if (buffer == NULL)
		{
			printf("cannot allocate memory\n");
		}
		sendbuffer = (char*)malloc(sizeof(char)*(PacketSize+10));
		if (sendbuffer == NULL)
		{
			printf("cannot allocate memory\n");
		}
		//compute how many packet need to send大文件分块传输
		PacketCount = lSize/PacketSize;
		//compute the size of last packet
		LastDataPacket = lSize - PacketSize*PacketCount;

		//convert int to char[] 这个函数和它的反函数都很有用。
		itoa(PacketCount,buffer_count,10);
		itoa(LastDataPacket,buffer_last,10);

		lastbuffer = (char*)malloc(sizeof(char)*(LastDataPacket+10));
		if (lastbuffer == NULL)
		{
			printf("cannot allocate memory\n");
		}

		//read the from file pointer to memory pointer
		result = fread(buffer,1,lSize,fp);
		if(result != lSize)
		{
			printf("cannot write the binary file to memory\n");
		}
		fclose(fp);

		bytesSent_count = send(m_socket,buffer_count,10,0);//发送这个大文件分成了多少个包
		if (bytesSent_count == SOCKET_ERROR) {
			wprintf(L"send failed with error: %d\n", WSAGetLastError());
			//closesocket(m_socket);
			//WSACleanup();
			break;
		}

		bytesSent_last = send(m_socket,buffer_last,6,0);//不能整除的这个包的大小
		if (bytesSent_last == SOCKET_ERROR) {
			wprintf(L"send failed with error: %d\n", WSAGetLastError());
			//closesocket(m_socket);
			//WSACleanup();
			break;
		}
		
		int iSendSize;
		int iSent;
		int idx;
		int i;
		for(i=0;i<PacketCount;i++)
		{

			itoa(i*PacketSize,temp,10);
			memcpy(sendbuffer,temp,10);
			memcpy(sendbuffer+10,buffer+i*PacketSize,PacketSize);//发送的思路是每个包分为两部分,前10个字符是这个包在整个大文件中的位置,后面就是这包得数据

			iSendSize = PacketSize + 10;
			idx = 0;
			while (iSendSize > 0)//这里是防粘包处理
			{
				iSent = send(m_socket,sendbuffer+idx,iSendSize,0);
				if (iSent > 0)
				{
					idx += iSent;
					iSendSize -= iSent;
				}
				else if (iSent == 0)
				{
					break;
				}
				else if (iSent == SOCKET_ERROR)
				{
					wprintf(L"send failed with error: %d\n", WSAGetLastError());
					//closesocket(m_socket);
					//WSACleanup();
					break;
				}
			}
		}
		itoa(i*PacketSize,temp,10);
		memcpy(lastbuffer,temp,10);
		memcpy(lastbuffer+10,buffer+i*PacketSize,LastDataPacket);
		iSendSize = LastDataPacket + 10;
		idx = 0;
		while (iSendSize > 0)
		{
			iSent = send(m_socket,lastbuffer+idx,iSendSize,0);
			if (iSent > 0)
			{
				idx += iSent;
				iSendSize -= iSent;
			}
			else if (iSent == 0)
			{
				break;
			}
			else if (iSent == SOCKET_ERROR)
			{
				wprintf(L"send failed with error: %d\n", WSAGetLastError());
				//closesocket(m_socket);
				//WSACleanup();
				break;
			}
		}

		free(buffer);
		free(sendbuffer);
		free(lastbuffer);
		str[20]++;//next pic
//		Sleep(2000);

	}




	int test1;

	scanf("%d",&test1);

	closesocket(m_socket);

	WSACleanup();


	return ;


}

接收端:

接收端是写在MFC里面,因为要用到GDI+的一个直接从内存读jpeg,然后画在窗口的函数。

	WSADATA wsaData;
	int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
	//if ( iResult != NO_ERROR )
	//	printf("Error at WSAStartup()\n");

	SOCKET m_socket;
	m_socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );//初始化socket对象
	//if ( m_socket == INVALID_SOCKET ) {
	//	printf( "Error at socket(): %ld\n", WSAGetLastError() );
	//	WSACleanup();
	//	return;	
	//}

	sockaddr_in service;

	service.sin_family = AF_INET;
	service.sin_addr.s_addr = inet_addr("163.180.117.229");
	service.sin_port = htons( 6000 );
	if ( bind( m_socket, (SOCKADDR*) &service, sizeof(service) ) == SOCKET_ERROR ) {//和端口绑定
		//printf( "bind() failed.\n" );
		closesocket(m_socket);
		return;
	}

	listen( m_socket, SOMAXCONN );//开始监听
	/*if ( listen( m_socket, SOMAXCONN ) == SOCKET_ERROR )
	printf( "Error listening on socket.\n");*/
	SOCKET AcceptSocket;
	//printf( "Waiting for a server to update...\n" );

	SOCKADDR_IN serverInfo;
	int len = sizeof(SOCKADDR);

	AcceptSocket = accept(m_socket , (SOCKADDR*)&serverInfo, &len);//接受发送端的socket
	//printf( "Client Connected.\n");

	int flag = 1;
	char str[30] = "C://Receive_Packet//1";
	char str_end[5] = ".JPG";
	strcat(str,str_end);//小技巧,产生存储文件的地址。
	int PackteSize = 1024;//对象发送端的最小包的单元
	int PacketCount,LastDataPacket;
	int lSzie;

	char* recvbuf;
	char* buffer_last;
	char* buffer;
	char recvbuf_count[10];
	char recvbuf_last[6];
	char temp[10];
	int pos;
	int bytesRecv,num;
	int bytesRecv_count,bytesRecv_last;

	HDC hdc = ::GetDC(m_hWnd);//获取窗口DC,画jpeg的时候用到
	IPicture* pPic;
	IStream* pStm;


	recvbuf = (char*)malloc(sizeof(char)*(PackteSize+10));
	/*	if (recvbuf == NULL)
	{
	printf("cannot allocate memory\n");
	}*/

	while(1)
	{

//		test = 0;

		FILE* fp = fopen(str,"wb");//创建写的文件流对象

		//receive the PacketCount
		bytesRecv_count = recv(AcceptSocket,recvbuf_count,10,0);//先接受这个大文件有多少个小包
		if ( bytesRecv_count == 0 )
			break;
	//	printf("Bytes received: %d\n", bytesRecv_count);
		PacketCount = atoi(recvbuf_count);

		//receive the LastDataPacket
		bytesRecv_last = recv(AcceptSocket,recvbuf_last,6,0);
		/*if ( bytesRecv_last > 0 )
		printf("Bytes received: %d\n", bytesRecv_last);*/
		LastDataPacket = atoi(recvbuf_last);

		lSzie = PackteSize * PacketCount + LastDataPacket;//计算出文件的大小,动态分配内存

	

		buffer_last = (char*)malloc(sizeof(char)*(LastDataPacket+10));
		/*if (buffer_last == NULL)
		{
		printf("cannot allocate memory\n");
		}*/

		buffer = (char*)malloc(sizeof(char)*lSzie);
		/*if (buffer == NULL)
		{
		printf("cannot allocate memory\n");
		}*/

		int iRecvSize;
		int iRet;
		int idx;

		int i;
		for (i=0;i<PacketCount;i++)
		{
			iRecvSize = PackteSize + 10;
			idx = 0;
			while (iRecvSize > 0)//防粘包的接受程序
			{
				iRet = recv(AcceptSocket, recvbuf+idx, iRecvSize, 0);
				if (iRet > 0)
				{
					idx += iRet;
					iRecvSize -= iRet;
				}
				else if (iRet == 0)
				{
					break;
				}
				else if ( iRet == SOCKET_ERROR)
				{
					break;
				}
			}
			//if ( bytesRecv > 0 )
			//	printf("Bytes received: %d\n", bytesRecv);
			//else if ( bytesRecv == 0 )
			//{
			//	printf("Connection closed\n");
			//	break;
			//}
			//else
			//{
			//	printf("recv failed: %d\n", WSAGetLastError());
			//	break;
			//}
			memcpy(temp,recvbuf,10);
			pos = atoi(temp);//字符串转整数,很好
			//if (pos == 0)
			//{
			//	test++;
			//}
		    memcpy(buffer+pos,recvbuf+10,PackteSize);//读出这个小包在整个大文件中的位置,写进到大文件对应中的位置
		}
		iRecvSize = LastDataPacket + 10;
		idx = 0;
		while (iRecvSize > 0)
		{
			iRet = recv(AcceptSocket, buffer_last+idx, iRecvSize, 0);
			if (iRet > 0)
			{
				idx += iRet;
				iRecvSize -= iRet;
			}
			else if (iRet == 0)
			{
				break;
			}
			else if ( iRet == SOCKET_ERROR)
			{
				break;
			}
		}
		/*	if ( bytesRecv > 0 )
		printf("Bytes received: %d\n", bytesRecv);
		else if ( bytesRecv == 0 )
		{
		printf("Connection closed\n");
		break;
		}
		else
		{
		printf("recv failed: %d\n", WSAGetLastError());
		break;
		}*/
		memcpy(temp,buffer_last,10);
		pos = atoi(temp);
		memcpy(buffer+pos,buffer_last+10,LastDataPacket);


		num = fwrite(buffer,lSzie,1,fp);

		fclose(fp);

		str[20]++;
		//flag = str[20];

		    HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE,lSzie);
                    LPVOID pvData = NULL;
                    pvData = GlobalLock(hGlobal);
                    memcpy(pvData,buffer,lSzie);
                    GlobalUnlock(hGlobal);
                    CreateStreamOnHGlobal(hGlobal,TRUE,&pStm);
                    ULARGE_INTEGER  pSeek;
                    LARGE_INTEGER  dlibMove  ={0};
                    pStm->Seek(dlibMove,STREAM_SEEK_SET,&pSeek);
                    OleLoadPicture(pStm,lSzie,TRUE,IID_IPicture,(LPVOID*)&pPic);


                    OLE_XSIZE_HIMETRIC hmWidth; 
                    OLE_YSIZE_HIMETRIC hmHeight; 
                    pPic->get_Width(&hmWidth);
                    pPic->get_Height(&hmHeight);
                    pPic->Render(hdc,0,0,320,200,0,hmHeight,hmWidth,-hmHeight,NULL);

                    GlobalFree(hGlobal);


                   free(buffer_last);
                   free(buffer);
	}


	free(recvbuf);
	pPic->Release();
	pStm->Release();


	//int i;

	//scanf("%d",&i);

	closesocket(AcceptSocket);

	WSACleanup();

	return;



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值