クライアント サーバー ソケット トランザクションをエミュレートしています。クライアントが次の IP パケットを送信したとします。
status = send(sock, packet, sizeof(struct iphdr) + sizeof(struct tcphdr),
0);
はsock
ソケットでpacket
、ip パケットを指します (ip header structiphdr
および tcp header struct を使用tcphdr
)
ここで、サーバー側で、データを取得して表示する関数を使用したいと考えていますpacket
。クライアントとサーバー間の接続は正しく設定されていますが、recv
機能を使用しようとすると、データが取得されません。正しいrecv
機能か
クライアント側では
packet = malloc(sizeof(struct iphdr)+ sizeof(struct tcphdr));
そして私は使用します
send(sock, packet, sizeof(struct iphdr) + sizeof(struct tcphdr),
0);
サーバー側では、いくつか宣言し、char packet[32];
これを使用しました
recv(sock, packet, 32, 0);
編集2 - これがコードです
クライアント側
クライアント側で編集します(短くするために、含まれているライブラリ、 、 、 については言及しませんでした。またstruct
iphdr
、tcpヘッダーをハイドレートしませんでした。今のところ、テストしたいだけです)tcphdr
in_chksum function
struct tcphdr tcp_hdr;
struct ip ip_hdr;
#define PORT 23
int sendmeifyoucan(SOCKET sock, SOCKADDR_IN * sin , int size ){
struct ip * ip = (struct ip *)malloc(sizeof(struct ip));
struct tcphdr * tcp;
char * packet;
int sock_err;
int psize=0, status = 1;
packet = malloc(sizeof(struct ip)+ sizeof(struct tcphdr));
memset(packet, 0, sizeof(struct ip) + sizeof(struct tcphdr));
ip->ip_len = htons(sizeof(struct ip) + sizeof(struct tcphdr) + psize);
ip->ip_hl = 5;
ip->ip_v = 4;
ip->ip_ttl = 255;
ip->ip_tos = 0;
ip->ip_off = 0;
ip->ip_p = IPPROTO_ICMP;
ip->ip_src.s_addr = inet_addr("127.0.0.1");
ip->ip_dst.s_addr = inet_addr("127.0.0.1");
ip->ip_sum = in_chksum((u_short *)ip, sizeof(struct ip));
status = send(sock, packet, sizeof(struct iphdr) + sizeof(struct tcphdr),
0);
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);
if(connect(sock, (SOCKADDR*)&sin, sizeof(sin)) != SOCKET_ERROR)
{
printf("Connection à %s sur le port %d\n", inet_ntoa(sin.sin_addr), htons(sin.sin_port));
sendmeifyoucan(sock, &sin,size);
/* Si l'on reçoit des informations : on les affiche à l'écran */
}
}
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;
}
編集 3 - ヘッダー
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/tcp.h>
#include <netinet/ip.h>
#include <unistd.h>
#define INVALID_SOCKET -1
#define SOCKET_ERROR -1
#define closesocket(s) close(s)
typedef int SOCKET;
typedef struct sockaddr_in SOCKADDR_IN;
typedef struct sockaddr SOCKADDR;
#include <stdio.h>
#include <stdlib.h>
#define PORT 23