如何从套接字读取所有服务器的响应?

时间:2009-03-18 22:57:56

标签: c sockets

我有一个非常大的问题......我正在使用C语言中的套接字。我向服务器发送了一个请求,它向我发送了许多响应。问题是客户端收到第一个响应,然后关闭连接。我能做什么?我尝试使用setsockopt() ... SO_KEEPALIVE或SO_LINGER,但我还没有解决问题。你能帮助我吗?非常感谢


这里要更清楚的是代码。套接字会在一段时间后或客户收到第一个回复后自动关闭......我不确定。

char* demarre_client( client_args * c_args,char* message, /*char* SERVEUR_PORT*/int port){
int socket_client=socket(PF_INET,SOCK_STREAM,0);
memset(&(c_args->adresse_serveur),0,sizeof(c_args->adresse_serveur));
c_args->adresse_serveur.sin_family=AF_INET;
c_args->adresse_serveur.sin_addr.s_addr=inet_addr(SERVEUR_IP);
//int port=APHash(SERVEUR_PORT,strlen(SERVEUR_PORT));
c_args->adresse_serveur.sin_port=htons(port);
int err=0;

if ((err=connect(socket_client, (struct sockaddr *) &(c_args->adresse_serveur), sizeof(c_args->adresse_serveur)))<0)
{
    printf("CONNECT error %d\n", errno);
    exit(-1);
}
if (send(socket_client, message, strlen(message), 0)!=strlen(message))
{
    printf("send error!!\n");
    exit(-2);
}
char* raspFin=(char* )malloc(sizeof(char)*1024);
strcpy(raspFin,"");
int num=-1;
int nn=0;
char* rasp=(char* )malloc(sizeof(char)*1024);
memset (rasp, 0, 1024 * sizeof(char ));
    /* here it reads the first response and after he get out of while */
while ((num=recv(socket_client, rasp,1024,MSG_WAITALL))>0)
{
    printf("recu %s mun=%d\n" , rasp,num);
    strcat(raspFin,rasp);
    strcat(raspFin,"\n");
    rasp=(char* )malloc(sizeof(char)*1024);
    memset (rasp, 0, 1024 * sizeof(char ));

}

if (num<0)
{
    printf("rasp error!!\n");
    exit(-3);
}

2 个答案:

答案 0 :(得分:4)

您确定在第一次通话时没有收到所有回复吗?

TCP / IP是内置流量控制的流协议,因此可以在一个send()中接收使用单独的recv()呼叫发送的不同消息。因为你使用printf(),它会打印缓冲区,直到它看到null-terminator - 可能是终结符之外的其他响应?

尝试使用某些流量控制,例如发送消息长度前缀或使用某些特殊字符(如STX / ETX,但请确保您的消息不包含此类字符)。如果您打算使用此软件,则无论如何都需要实施一些流量控制。

现在尝试用

替换printf()
char *ptr;
for (ptr = buffer; ptr <= buffer + num; ptr += strlen(ptr)+1;)
    printf("%s\n", ptr);

它将打印您的响应缓冲区中的所有字符串。

你在循环中不需要malloc() - 你泄漏了内存。

BTW SO_KEEPALIVESO_LINGER与此问题无关。

答案 1 :(得分:2)

我的建议是启动Wireshark network analyzer并查看正在发生的数据包。在过滤器集

tcp.srcport == <insert_server_port> || tcp.dstport == <insert_server_port>

您应该看到实际发送的数据和关闭连接的人(发送FIN / RST数据包)。