【发布时间】:2013-06-14 11:16:42
【问题描述】:
我对套接字编程很陌生,我想模拟一个客户端-服务器事务。所以对于我的客户端发送的数据包,我声明了一个sock = socket(AF_INET, SOCK_STREAM, 0),一个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;
}
【问题讨论】:
-
@nos 我已经编辑了我的帖子
-
@nos 哦,是的,我确实错过了,(顺便说一句,我在 osx 上使用 Xcode)
-
@nos 所以我编辑了我的帖子,实际上似乎函数 recv(sock, buffer, 32, 0) 从未执行过。我想,当 sendto 函数被处理时,接受的连接可以将数据传递给 recv 函数。我错过了什么吗?
标签: c sockets client-server