利用最基本的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;