UDP客户端无法从C

时间:2016-11-07 21:11:09

标签: c linux sockets udp

所以我试图在Linux中使用UDP和C创建一个基本的服务器和客户端。服务器必须从客户端接收两个char数组(缓冲区和辅助),并且客户端必须从服务器接收一个int数组,该数组将包含aux中给出的字符位于缓冲区数组中的位置(例如,如果我们有aaabaa和a aux,客户必须打印01245)。问题是客户端总是打印00000等,具体取决于frecv数组的长度。

这是我的代码:

//客户端

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#include <netdb.h> 
#include <stdint.h>

int main(int argc, char *argv[])
{

int clientSocket, portNum, nBytes1,portno,nBytes2,nBytes3,i;
int32_t frecv[1024],frecv2[1024];
char buffer[1024],aux[2];
struct sockaddr_in serverAddr;
socklen_t addr_size;
struct hostent *server1;

clientSocket = socket(PF_INET, SOCK_DGRAM, 0);
portno=atoi(argv[2]);
server1 = gethostbyname(argv[1]);
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(portno);
bcopy((char *)server1->h_addr, (char *)&serverAddr.sin_addr.s_addr,server1->h_length);;
memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);  

addr_size = sizeof serverAddr;

while(1)
{
    printf("Introdu un sir de caractere:\n");
    fgets(buffer,1024,stdin);
    printf("You typed: %s\n",buffer);

    printf("Introdu un caracter:\n");
    fgets(aux,2,stdin);
    printf("You typed: %s\n",buffer);
    printf("You typed: %s\n",aux);

    nBytes1 = strlen(buffer) + 1;
    nBytes2 = strlen(aux) + 1;
    sendto(clientSocket,buffer,nBytes1,0,(struct sockaddr *)&serverAddr,addr_size);
    sendto(clientSocket,aux,nBytes2,0,(struct sockaddr *)&serverAddr,addr_size);

    nBytes3 = recvfrom(clientSocket,frecv2,1024,0,(struct sockaddr *)&serverAddr,&addr_size);
    for (i = 0 ; i < nBytes3 ; i++) 
        frecv[i] = ntohl(frecv2[i]);
    for (i=0;i<nBytes3;i++)
        printf("%d",frecv[i]);
    printf("\n");
    return 0;
}


}

//服务器

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#include <netdb.h> 
#include <stdint.h>

int main(int argc, char *argv[])
{
int udpSocket,portno,l;
char buffer[1024];
char aux[2];
struct sockaddr_in serverAddr,client;
socklen_t addr_size;
int i;

udpSocket = socket(AF_INET, SOCK_DGRAM, 0);
if (udpSocket < 0) 
{
    printf("Eroare la crearea socketului server\n");
    return 1;
}
memset(&serverAddr, 0, sizeof(serverAddr));
portno=atoi(argv[1]);
serverAddr.sin_port = htons(portno);
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = INADDR_ANY;


if (bind(udpSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr)) < 0)
{
    perror ("Eroare la bind");
    exit (1);
}
else
    printf ("Bind successful\n");

l = sizeof(client);
memset(&client, 0, sizeof(client));

while(1)
{
    int nBytes1,nBytes2,j;
    int32_t frecv[1024],frecv2[1024];
    nBytes1 = recvfrom(udpSocket,buffer,1024,0,(struct sockaddr *)&client, &l);
    nBytes2 = recvfrom(udpSocket,aux,2,0,(struct sockaddr *)&client, &l);

    printf("You typed: %s\n",buffer);
    printf("You typed: %s\n",aux);
    printf("You typed: %d\n",nBytes1);
    printf("You typed: %d\n",nBytes2);

    for(i=0;i<nBytes1-1;i++)
        if (buffer[i]==aux[0])
        {
            frecv[j]=i;
            j++;
        }
    for(i=0;i<j;i++)
        printf("%d",frecv[i]);
    for (i = 0 ; i < j ; i++) 
        frecv2[i] = htonl(frecv[i]);
    printf("\n");
    sendto(udpSocket,frecv2,j,0,(struct sockaddr *)&client,l);
    printf("Done\n");
}

return 0;
}

1 个答案:

答案 0 :(得分:2)

关于服务器响应时要发送/接收的数据量,您已经关闭了。

在服务器中:

sendto(udpSocket,frecv2,j,0,(struct sockaddr *)&client,l);

您不希望发送j个字节。您想要发送j类型的int32_t元素。所以你需要乘以元素大小。

sendto(udpSocket,frecv2,j*sizeof(frecv2[0]),0,(struct sockaddr *)&client,l);

同样在客户端:

for (i = 0 ; i < nBytes3 ; i++) 
    frecv[i] = ntohl(frecv2[i]);
for (i=0;i<nBytes3;i++)
    printf("%d",frecv[i]);

您阅读nBytes3,但每个元素的大小为int32_t,而不仅仅是1个字节。因此除以元素大小:

for (i = 0 ; i < nBytes3 / sizeof(frecv2[0]) ; i++) 
    frecv[i] = ntohl(frecv2[i]);
for (i=0;i<nBytes3 / sizeof(frecv2[0]);i++)
    printf("%d",frecv[i]);

服务器中还有一件事。您无法初始化j。将它设置为循环顶部的0。