【发布时间】:2013-06-17 12:23:41
【问题描述】:
我正在模拟客户端-服务器套接字事务。假设,客户端发送了一些带有
的 ip 数据包status = send(sock, packet, sizeof(struct iphdr) + sizeof(struct tcphdr),
0);
其中sock 是套接字,packet 指向一个ip 数据包(带有ip 头结构iphdr 和tcp 头结构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 - 这是代码
在客户端
在客户端编辑(为了缩短,我没有提到包含的库,structiphdr、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
【问题讨论】:
-
是的,你必须使用
recv()。请给我们一些代码。 -
@nouney 请在我的帖子中查看我的更新
-
返回
send()和recv ?() -
@nouney
send()返回 '48' 而 recv 什么也不返回... -
当您按原样发送结构时,它可能有填充以对齐它。你能发布你的 iphdr 和 tcphdr 结构吗?另外,您能否让我们知道您首先打开的是哪种类型的插座?
标签: c sockets client-server