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