Tutorial : les sockets sous win (tcp & udp)

Soyez le premier à donner votre avis sur cette source.

Vue 37 318 fois - Téléchargée 5 611 fois

Description

Ce tut est composé de :
_Un client TCP
_Un server TCP
_Un envoyeur de packets udp
_Un receveur de packets udp
+ Un code qui fait tout a la fois (+pratik)

Le tout commenté bien sur :)

J'y ai ajouté qq document que j'ai utilisé pour comprendre le fonctionement des sockets.

Conclusion :


J'espere que sa aidera ceux qui débutent en la matiere.

Codes Sources

A voir également

Ajouter un commentaire Commentaires
Messages postés
1
Date d'inscription
jeudi 3 juillet 2008
Statut
Membre
Dernière intervention
2 décembre 2010

merci, même si j'aurai aimer voir l'utilisation des fonction WSASend() et WSARecv()
Messages postés
1
Date d'inscription
vendredi 11 juillet 2008
Statut
Membre
Dernière intervention
11 juillet 2008

Bon tuto.
Dans UDP_Packet_Sender.cpp, le 4ème paramètre de la fonction sendto(...) permet de spécifier des flags de contrôle de la socket (c.f http://msdn.microsoft.com/en-us/library/ms740148(VS.85).aspx ).

HTH ;)
Utilisateur anonyme
j'ai posé ma question sur le forum: http://www.cppfrance.com/infomsg_UDP_968594.aspx
Utilisateur anonyme
Bonjours (bonne source merci).
J'ai une question.

En TCP on sait que si l'on doit recevoir par exemple 1024 Octects. On va faire recv() et si avec le premier recv() on recoit pas les 1024 octects on va refaire recv() autant de fois qu'il le faudra pour pouvoir mettre bout à bout les 1024 octects.

Mais en UDP comment cela fonctionnne si on recoit pas les 1024 octects prevu avec recvfrom(), on perd le reste des données ?
Où doit-on refaire recvfrom() tant qu'il le faudra comme en TCP ?

Merci
Messages postés
16
Date d'inscription
jeudi 16 novembre 2006
Statut
Membre
Dernière intervention
29 janvier 2016

Bonjour,

J'ai trouvé un code qui est très intéressant, mais qui ne me permet pas de recevoir des fichiers.
Je peux recevoir ce que dit le serveur (ce qui est intéressant, mais pas pour le moment).
A partir du moment où je suis sur le point de recevoir un fichier, il me met :
450 Write Error: bad file descriptor.
C'est de l'envoi FTP, pas HTTP (j'ai le même en HTTP, ca marche très bien).
Est-ce que quelqu'un sait ce qu'il me manque pour que ca fonctionne ??
Merci.

voici le code :
#include "stdafx.h"
#include <stdio.h>
#include <winsock.h>
#include "wininet.h"

#ifndef SD_SEND
#define SD_SEND 1
#endif

#define BUFFER_SIZE 5*1024
static HWND hDlg;
static BYTE buff[BUFFER_SIZE], *Buffer;
#define Mes(szTXT) MessageBoxA(hDlg, szTXT,"nvond",MB_OK);
static bool init_winsock(void)
{
WSAData Data;
int Code;
std::ostringstream oss;
if((Code=WSAStartup(MAKEWORD(1, 1),&Data)) != 0)
{
oss<<"erreur dans WSAStartup() : "<<Code;
// printf("erreur dans WSAStartup() : %d\n", Code);
return false;
}
return true;
}

static SOCKET etablir_connexion(u_long adresse_distante, u_short port) {
sockaddr_in sinDistant;
SOCKET sd = socket(AF_INET, SOCK_STREAM, 0);

if(sd!=INVALID_SOCKET) {
sinDistant.sin_family = AF_INET;
sinDistant.sin_addr.s_addr = adresse_distante;
sinDistant.sin_port = port;
if(connect(sd,(sockaddr*)&sinDistant, sizeof(sockaddr_in))==SOCKET_ERROR)
sd = INVALID_SOCKET;
}
return sd;
}

static u_long resoudre_adresse(char* hote) {
hostent* pHE;
u_long adresse_distante = inet_addr(hote);

if(adresse_distante == INADDR_NONE) {
pHE = gethostbyname(hote);
if(pHE == 0) return INADDR_NONE;
adresse_distante = *((u_long*)pHE->h_addr_list[0]);
}
return adresse_distante;
}

static int connectionFtp(HWND hwnd, std::string adr)
{
char *Hote = "anonymous.ftp.ovh.net";//"ftp.free.fr";//"cns.free.fr";
int Port = 21;

init_winsock();

u_long adresse;
SOCKET sd;
char *requete;
char tampon;

// Trouver l'adresse de l'hôte
std::ostringstream oss;
oss<<"Recherche de l'hôte... "<< Hote;
MessageBoxA(hwnd,oss.str().c_str(),"xj",MB_OK);
oss.clear();
adresse = resoudre_adresse(Hote);
if(adresse==INADDR_NONE)
{
MessageBoxA(hwnd,"Echec !","xj",MB_OK);
// printf("Echec !\n");
return 3;
}
MessageBoxA(hwnd,"Connexion en cours !","xj",MB_OK);
//printf("Connexion en cours !\n");
sd = etablir_connexion(adresse, htons(Port));
if(sd!=INVALID_SOCKET) printf("Connecté !\n");

// envoi de la requête
requete="ftp anonymous.ftp.ovh.net\r\nUSER anonymous\r\nPASS a.a@msn.fr\r\nCWD ankamagam\r\nREST 0\r\nRETR Errata.txt\r\nquit\r\n\r\n";//\r\n/*RETR Errata.txt\r\n*/
send(sd, requete, (int)strlen(requete), 0);
std::ostringstream oss1;
// réception de la réponse
DWORD Recu=0;
DWORD Ecrit=0;
int rep;
while(rep=recv(sd,&tampon,1,0)!=0 )
{
regarder(rep);
regarderConnect(rep);
oss1<<tampon;
// Recu++;
// printf("%c", tampon);
}
//oss1<<tampon;
MessageBoxA(hwnd,oss1.str().c_str(),"xj",MB_OK);
/*
if(oss1.str().c_str()[Recu-3]=='1' && oss1.str().c_str()[Recu-2]=='2' && oss1.str().c_str()[Recu-1]=='5')
{
oss1.clear();
std::ostringstream oss2;
Recu=0;
while(recv(sd,tampon,1,0)!=0 && !(oss2.str().c_str()[Recu-2]==')' && oss2.str().c_str()[Recu-1]=='.'))
{
oss2<<tampon;
Recu++;
}
MessageBoxA(hwnd,oss2.str().c_str(),"xj",MB_OK);
}*/
//hOpenFile = ::FtpOpenFileA(hConnect,strFileNameAtServer.c_str(), GENERIC_READ, FTP_TRANSFER_TYPE_BINARY, 1);

FILE* File;
//BYTE* Buffer;
char* buffer=new char[4*1024];
File = (FILE*)CreateFileA("Errata.txt", FILE_ALL_ACCESS, FILE_SHARE_WRITE, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
HANDLE hOpenFile = NULL;
DWORD ToRead=4*1024;
DWORD Size=24017;

// HINTERNET hOpenFile;
HINTERNET hConnect = NULL;
hOpenFile = ::FtpOpenFileA(hConnect,"Errata.txt", GENERIC_READ, FTP_TRANSFER_TYPE_BINARY, 1);
if (!InternetReadFile (hOpenFile, (LPVOID)Buffer, ToRead, &Size) )
{
fclose (File);
//CString strMsg;
//string strReposeFromServer;
//GetLastResponse(strReposeFromServer);
//strMsg.Format(L"Error:%d\nDescription:%s", GetLastError(), strReposeFromServer.c_str());
//AfxMessageBox(strMsg, MB_OK);
return 0;
}
WriteFile(File, Buffer, Recu, &Ecrit, 0);
//MessageBoxA(hwnd,oss1.str().c_str(),"xj",MB_OK);

MessageBoxA(hwnd,"FINI","oxi",MB_OK);
// quitter correctement winsock
send(sd,"quit\r\n\r\n", (int)strlen(requete), 0);
shutdown(sd, SD_SEND);
closesocket(sd);
WSACleanup();
return 0;
}
Afficher les 22 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.