Cómo transferir archivos usando programación de socket basada en mfc
1. Adopte un método de subprocesos múltiples, use AfxBeginThread() para abrir un nuevo hilo al transferir archivos
void CClientsockDlg::OnBnClickedSend()
{
{
p>
pThreadSend = AfxBeginThread(Thread_Send,this);/
}
Se abren nuevos hilos para enviando y recibiendo archivos
UINTThread_Send( LPVOID lpParam)
{
El código se omite...
}
2. Admite la obtención de parámetros del servidor desde el archivo de configuración configuración.ini
Utilice GetPrivateProfileString() y GetPrivateProfileInt() para obtener la IP de tipo String y el puerto de tipo int ubicados en el archivo ServerConfiguration.ini respectivamente<. /p>
CString IP;
int puerto;
GetPrivateProfileString
(L"ServerConfiguration",L"IP",L"No se leyeron datos !",IP.GetBuffer(10),10,L". \\configuration.ini");
port=GetPrivateProfileInt(L"ServerConfiguration",L"puerto",0,L".\ \configuration.ini");
3. Adoptando un método de diseño orientado a objetos, las funciones se dividen en módulos
El propio MFC tiene buenas características orientadas a objetos. Este programa está escrito estrictamente de acuerdo con la estructura del marco MFC. Cada botón corresponde a una función funcional. Reduce el acoplamiento entre códigos y facilita la expansión y reutilización del programa.
void CServversockDlg::OnBnClickedChoose()
void CServversockDlg::OnBnClickedSend()
void CServversockDlg::OnBnClickedRecvdata()
void CServersockDlg::OnBnClickedAbout()
void CServersockDlg::OnBnClickedWriteini()
4. Usando la clase CSocket, el código es relativamente simple
La clase CSocket es un marco MFC encapsula winsockAPI en la programación de sockets, por lo que es más conveniente administrar el envío y la recepción de datos a través de esta clase. El código también es simple y fácil de entender.
//Crear
if(!Clientsock.Socket())
{
CString str;
str.Format(_T("Error al crear el socket: %d"),GetLastError());
AfxMessageBox(str);
}
/ /Conectar
if(!Clientsock.Connect(IP,puerto))
{
CString str;
str.Format( _T("Error en la conexión del socket: %d"),GetLastError());
AfxMessageBox(str);
}
else
{
AfxMessageBox(_T("Conexión de socket exitosa"));
El código se omite...
//Enviar
while (nSize { szBuff = new char[1024]; memset(szBuff,0x00,1024); nSend =file.Read(szBuff,1024); Clientsock.Send(szBuff,nSend);//Enviar datos nSize += nSend; } archivo.Close(); eliminar szBuff; Clientsock.Close(); (dlg- >GetDlgItem(IDC_SEND))->EnableWindow(TRUE); AfxMessageBox(_T("El archivo se envió correctamente")); dlg->SetDlgItemTextW(IDC_FILEPATHNAME, _T("" )); } devuelve 0; 5. Admite la transmisión bidireccional de datos entre el servidor y el cliente Este programa no solo se pueden transferir archivos del cliente al servidor, sino que también se pueden transferir archivos del servidor al cliente. Pero los métodos para transferir archivos entre sí no son exactamente los mismos. Ya sea que esté recibiendo o enviando archivos, el servidor siempre escucha el puerto vinculado. //Enlace if(!Serversock.Bind(port)) { CString str; str.Format(_T("Error en el enlace del socket: %d"),GetLastError()); AfxMessageBox(str); } //Escucha if(!Serversock.Listen(10)) { CString str; str.Format (_T ("Error en la supervisión del socket: %d"),GetLastError()); AfxMessageBox(str); } El cliente no recibe el archivo o enviar archivo siempre está conectado. if(!Clientsock.Connect(IP,puerto)) { CString str; str.Format(_T( "Error en la conexión del socket: %d"),GetLastError()); AfxMessageBox(str); } else { Un poco... 6. Interfaz gráfica de operación completa 2. Instrucciones para usar el software La interfaz principal del cliente es como se muestra en la figura: Haga clic en "Seleccionar archivo" para que aparezca el cuadro de diálogo del archivo, seleccione el archivo que desea enviado y guarde la ruta del archivo. Haga clic en "Enviar" para leer la información de configuración (IP y puerto) en el archivo ServerConfiguration.ini, establecer una conexión Socket basada en esta información y enviar el archivo. Nota: El servidor debe hacer clic primero en "Aceptar datos del cliente"; de lo contrario, el envío fallará. Al hacer clic en "Recibir", también se leerá la información de configuración (IP y puerto) en el archivo ServerConfiguration.ini y se establecerá una conexión de Socket basada en esta información para recibir archivos. Nota: El servidor primero debe seleccionar el archivo que se enviará al cliente y hacer clic en "Enviar", de lo contrario la aceptación fallará. Haga clic en "Leer archivo de configuración" para leer la información de configuración del archivo ServerConfiguration.ini y mostrarla en texto editable. Después de la modificación, haga clic en "Escribir archivo de configuración", la información modificada se guardará en la configuración. archivo. Haga clic en "Acerca de" para obtener más información sobre el software. Hay instrucciones más detalladas en los comentarios del código La interfaz principal del servidor es como se muestra en la figura u Haga clic en "Aceptar datos del cliente" para comience a monitorear el enlace del terminal del cliente. u Haga clic en "Seleccionar archivo" para que aparezca el cuadro de diálogo del archivo, seleccione el archivo que desea enviar y guarde la ruta del archivo. u Haga clic en "Enviar" para leer la información de configuración (puerto) en el archivo ServerConfiguration.ini, escuche el puerto correspondiente y prepárese para enviar el archivo. Nota: El envío sólo puede realizarse correctamente después de que el cliente seleccione "Recibir". u Haga clic en "Leer archivo de configuración" para leer la información de configuración del archivo ServerConfiguration.ini y mostrarla en forma de texto editable. Después de la modificación, haga clic en "Escribir archivo de configuración" para guardar la información modificada en el archivo. archivo de configuración. Sin embargo, la IP del servidor no se puede modificar. Se obtiene de la tarjeta de red de la máquina donde se encuentra el servidor cuando el programa comienza a ejecutarse. u Haga clic en "Acerca de" para obtener información relacionada con el software. u Hay instrucciones más detalladas en los comentarios del código Dirección de descarga del código:/detail/leixiaohua1020/6320417 Adjunte aquí el cliente que usa CSocket para iniciar una código de conexión [cpp] ver copia simple //-------------------------- --Hilo que envía archivos------------------------------ UINT Thread_Send(LPVOID lpParam) { CClientsockDlg *dlg=(CClientsockDlg *)lpParam; (dlg->GetDlgItem(IDC_SEND))->EnableWindow(FALSE); > CSocket Clientsock; //socket de definición if(!AfxSocketInit()) { AfxMessageBox(IDP_SOCKETS_INIT_FAILED } CString IP; int puerto; GetPrivateProfileString(L"ServerConfiguration",L"IP",L"¡no se leyeron datos! ",IP.GetBuffer(100),100,L".\\configuration.ini"); port=GetPrivateProfileInt(L"ServerConfiguration",L"puerto",0,L".\ \ configuración.ini"); //Crear if(!Clientsock.Socket()) { CString str ; str.Format(_T("Error al crear el socket: %d"),GetLastError()); AfxMessageBox(str); p> //Conectar // if(!Clientsock.Connect(_T("127.0.0.1"),8088)) if(!Clientsock.Connect ( IP, puerto)) { CString str; str.Format(_T("Error en la conexión del socket: %d"),GetLastError() ) AfxMessageBox(str); } else { AfxMessageBox(_T(" Enchufe; conexión exitosa")); WIN32_FIND_DATA FindFileData; CString strPathName; //Defina el objeto CString utilizado para guardar la ruta del archivo enviado > dlg->GetDlgItemTextW(IDC_FILEPATHNAME,strPathName) FindClose(FindFirstFile(strPathName,&FindFileData) Clientsock.Send(&FindFileData,sizeof(WIN32_FIND_DATA)); > Archivo CFile; if(!file.Open(strPathName,CFile::modeRead|CFile::typeBinary)) { AfxMessageBox. (_T("El archivo no existe")); devuelve 1 } UINT nSize = 0 UINT; nEnviar = 0; char *szBuff=NULL; //Enviar while(nSize { szBuff = new char[1024]; memset(szBuff,0x00,1024); nSend = file.Read(szBuff,1024); /p> p> Clientsock.Send(szBuff,nSend);//Enviar datos nSize += nSend } file.Close() ; eliminar szBuff Clientsock.Close() (dlg->GetDlgItem(IDC_SEND))->EnableWindow( TRUE); AfxMessageBox(_T("El archivo se envió correctamente")); dlg->SetDlgItemTextW(IDC_FILEPATHNAME,_T("")); } return 0; } Y el código del lado del servidor usando la supervisión de CSocket: [cpp] ver copia simple / /-------------------------------Hilo que escucha archivos------ ----------- ------------- UINT Thread_Func(LPVOID lpParam) //Función de subproceso para recibir archivos { CServersockDlg * dlg = (CServersockDlg *)lpParam //Obtener el puntero del diálogo (dlg->GetDlgIt; em(IDC_RECVDATA))->EnableWindow(FALSE); if(!AfxSocketInit()) { AfxMessageBox(IDP_SOCKETS_INIT_FAILED } CString IP; int puerto; GetPrivateProfileString(L"ServerConfiguration",L"IP",L"¡no se leyeron datos! ",IP.GetBuffer(100),100,L".\\configuration.ini"); port=GetPrivateProfileInt(L"ServerConfiguration",L"puerto",0,L".\ \ configuración.ini"); char errBuf[100]={0};//Caché temporal SYSTEMTIME t; //Estructura de tiempo del sistema CFile logErrorfile; if(!logErrorfile.Open(_T("logErrorfile.txt"),CFile::modeCreate|CFile::modeReadWrite)) { devolver 1; } CSocket Serversock; CSocket Clientsock //Crear si; (!Serversock.Socket()) { CString str str.Format(_T("Error al crear el socket: %d"), GetLastError ()); AfxMessageBox(str); } BOOL bOptVal = VERDADERO int bOptLen = sizeof(BOOL ) Serversock.SetSockOpt(SO_REUSEADDR,(void *)&bOptVal,bOptLen,SOL_SOCKET //Enlace if(!Serversock.Bind (puerto); )) { CString str; str.Format(_T("Error en el enlace del socket: %d"),GetLastError()) p> AfxMessageBox(str); } //Escuchar if(!Serversock.Listen(10)) { CString str str.Format(_T("Error en la supervisión del socket: %d"),GetLastErro r()); AfxMessageBox(str); } GetLocalTime(&t); sprintf_s(errBuf,"Servidor); Ya comenzó...Esperando recibir archivos...\r\nHora: %d año %d mes %d día %2d:%2d:%2d \r\n",t.wAño,t.wMes,t . wDay, t.wHour,t.wMinute,t.wSecond); int len = strlen(errBuf); logErrorfile.Write( errBuf ,len); AfxMessageBox(_T("Iniciar correctamente, esperando recibir archivos")); while(1) { //AfxMessageBox(_T("El servidor se inició correctamente...")); if(!Serversock.Accept(Clientsock)) //Esperando recepción { continuar } más { WIN32_FIND_DATA FileInfo Clientsock.Receive (&FileInfo,sizeof(WIN32_FIND_DATA)); archivo CFile file.Open(FileInfo.cFileName,CFile::modeCreate|CFile::modeWrite <); /p> //AfxMessageBox(FileInfo.cFileName); int length = sizeof(FileInfo.cFileName); logErrorfile.Write(FileInfo.cFileName,length); //Recibir datos del archivo UINT nSize = 0; UINT nData = 0 char *szBuff=NULL; /p> while(nSize { szBuff = new char[1024] memset(szBuff,0x00, 1024); nData=Clientsock.Receive(szBuff,1024); archivo.Write(szBuff,nData); nSize+=nData; } eliminar szBuff Serversock.Close() Clientsock.Close(); p> p> file.Close(); (dlg->GetDlgItem(IDC_RECVDATA))->EnableWindow(TRUE); sprintf_s(errBuf, "Archivo recibido exitosamente...\r\nHora: %d año %d mes %d día %2d:%2d:%2d \r\n",t.wAño,t.wMes,t.wDía, t.wHour,t.wMinute,t.wSecond); int len = strlen(errBuf); logErrorfile.Write(errBuf,len); //AfxMessageBox(_T("El archivo se recibió correctamente...")); break } } devuelve 0; }