私はソケットプログラミングが初めてで、クライアントサーバートランザクションをシミュレートしたいと考えています。したがって、クライアントが送信したパケットに対して、 a sock = socket(AF_INET, SOCK_STREAM, 0)
、 aを宣言し、SOCKADDR_IN sin
を介してそれらをバインドしますbind(sock, (SOCKADDR*) &sin, sizeof(sin))
。次に、クラシックstruct
ip ヘッダーを宣言し、struct iphdr * ip
にメモリを割り当ててハイドレートした後、最後に ip を介してパケットを送信します
sent_packet = sendto(sock, packet, sizeof(struct iphdr) + sizeof(struct tcphdr),
0, (struct sockaddr *) sin, sizeof(struct sockaddr));//sent_packet is an int, I use also a TCP header struct, packet is the pointer that stores the ip and tcp data
これはうまくいくようです。しかし今、私は送信されたパケットを追跡したいので、サーバー側のファイルを使用して を再度宣言sock
しSOCKADDR_IN client_sin
ますaccept(sock, (SOCKADDR*)&client_sin, &recsize);
。私はそれを使用してrecv(sock, buffer, 32, 0) != SOCKET_ERROR
パケットをキャッチします (もちろん、クライアント プログラムの前にサーバー プログラムを起動しました)。完全に間違っていますか?
Edit on the client side (to shorten, I didn't mention the included libraries, the `struct` `iphdr`, `tcphdr`, the `in_chksum function`, as well I didn't hydrate the tcp header, for now I just want to test)
#define PORT 23
int sendmeifyoucan(SOCKET sock, SOCKADDR_IN * sin , int size ){
struct iphdr * ip = (struct iphdr *)malloc(sizeof(struct iphdr *));
struct tcphdr * tcp;
char * packet;
int psize=0, status = 1;
printf("%d I am lost in the web ",status);
packet = malloc(sizeof(struct iphdr)+ sizeof(struct tcphdr));
memset(packet, 0, sizeof(struct iphdr) + sizeof(struct tcphdr));
sin->sin_addr.s_addr = inet_addr("127.0.0.1");
ip->tot_len = htons(sizeof(struct iphdr) + sizeof(struct tcphdr) + psize);
ip->ihl = 5;
ip->version = 4;
ip->ttl = 255;
ip->tos = 0;
ip->frag_off = 0;
ip->protocol = IPPROTO_ICMP;
ip->saddr = sin->sin_addr.s_addr;
ip->daddr = sin->sin_addr.s_addr;
ip->check = in_chksum((u_short *)ip, sizeof(struct iphdr));
status = sendto(sock, packet, sizeof(struct iphdr) + sizeof(struct tcphdr),
0, (struct sockaddr *) sin, sizeof(struct sockaddr));
free(packet);
return 0;
}
int main(void)
{
int erreur = 0;
SOCKADDR_IN sin;
SOCKET sock;
SOCKADDR_IN csin;
SOCKET csock;
int sock_err;
if(!erreur)
{
sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock != INVALID_SOCKET)
{
printf("La socket %d est maintenant ouverte en mode TCP/IP\n", sock);
int size = 0;
/* Configuration */
sin.sin_addr.s_addr = inet_addr("127.0.0.1");
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
/* Listage du port */
sendmeifyoucan(sock, &sin,size);
printf("Fermeture de la socket client\n");
closesocket(csock);
printf("Fermeture de la socket serveur\n");
closesocket(sock);
printf("Fermeture du serveur terminée\n");
}
else
perror("socket");
}
return EXIT_SUCCESS;
}
サーバー側で編集
#define PORT 23
int main(void)
{
int erreur = 0;
SOCKET sock;
SOCKADDR_IN sin;
socklen_t recsize = sizeof(sin);
SOCKADDR_IN csin;
char buffer[32] = "";
int sock_err;
if(!erreur)
{
sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock != INVALID_SOCKET)
{
printf("La socket %d est maintenant ouverte en mode TCP/IP\n", sock);
/* Configuration */
csin.sin_addr.s_addr = inet_addr("127.0.0.1");
csin.sin_family = AF_INET;
csin.sin_port = htons(PORT);
sock_err = bind(sock, (SOCKADDR*) &csin, sizeof(csin));
if(sock_err != SOCKET_ERROR)
{
sock_err = listen(sock, 5);
printf("Listage du port %d...\n", PORT);
}
if(sock_err != SOCKET_ERROR)
{
/* Attente pendant laquelle le client se connecte */
printf("Patientez pendant que le client se connecte sur le port %d...\n", PORT);
sock = accept(sock, (SOCKADDR*)&sin, &recsize);
}
if(recv(sock, buffer, 32, 0) != SOCKET_ERROR)
{
printf("Recu : %s\n", buffer);
}
else
{
printf("Impossible de se connecter\n");
}
closesocket(sock);
}
else
perror("socket");
}
return EXIT_SUCCESS;
}