我正在模拟客户端-服务器套接字事务。假设,客户端发送了一些 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
,tcphdr
,in_chksum function
,以及我没有水合 tcp 标头,现在我只想测试)
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