我对套接字编程很陌生,我想模拟一个客户端-服务器事务。因此,对于我的客户端发送的数据包,我声明 a sock = socket(AF_INET, SOCK_STREAM, 0)
, a SOCKADDR_IN sin
,我通过绑定它们bind(sock, (SOCKADDR*) &sin, sizeof(sin))
,然后,在声明一个经典的struct
ip 标头并为 a 分配一些内存后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
这似乎有效。但是现在,我想跟踪发送的数据包,所以我使用服务器端文件再次声明a sock
,我声明aSOCKADDR_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;
}