【问题标题】:Cannot receive a String with socket无法接收带有套接字的字符串
【发布时间】:2013-04-28 18:04:47
【问题描述】:

我想将一个整数和一个字符串从 Java 服务器发送到 C 客户端。我可以读取整数,但读取字符串时遇到问题。这是我在 java 中的服务器代码

ClientNumber++;
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
//dos.flush();
dos.writeInt(ClientNumber);

String randomString= getRandomValue(10,20);
dos.writeUTF(randomString);

这是 C 客户端代码:

int to_server_socket = -1;

void main ( void )
{

    char *server_name = SERVEURNAME;
    struct sockaddr_in serverSockAddr;
    struct hostent *serverHostEnt;
    long hostAddr;
    long status;
    char buffer[512];

    bzero(&serverSockAddr,sizeof(serverSockAddr));
    hostAddr = inet_addr(SERVEURNAME);
    if ( (long)hostAddr != (long)-1)
        bcopy(&hostAddr,&serverSockAddr.sin_addr,sizeof(hostAddr));
    else
    {
        serverHostEnt = gethostbyname(SERVEURNAME);
        if (serverHostEnt == NULL)
        {
            printf("gethost rate\n");
            exit(0);
        }
        bcopy(serverHostEnt->h_addr,&serverSockAddr.sin_addr,serverHostEnt->h_length);
    }
    serverSockAddr.sin_port = htons(8071);
    serverSockAddr.sin_family = AF_INET;

    /* creation de la socket */
    if ( (to_server_socket = socket(AF_INET,SOCK_STREAM,0)) < 0)
    {
        printf("creation socket client ratee\n");
        exit(0);
    }
    /* requete de connexion */
    if(connect( to_server_socket,
               (struct sockaddr *)&serverSockAddr,
               sizeof(serverSockAddr)) < 0 )
    {
        printf("demande de connection ratee\n");
        exit(0);
    }
    /* envoie de donne et reception */

    int value = htonl( 6 );
    int reply = 0;

    if( send( to_server_socket, &value, sizeof( value ), 0 ) != sizeof( value ) )
    {
        printf( "socket write failed");
        exit( -1 );
    }

    if( recv( to_server_socket, &reply, sizeof( reply ), MSG_WAITALL ) != sizeof( reply ) )
    {
        printf( "socket read failed");
        exit( -1 );
    }

    printf( "got reply: %d\n", ntohl( reply ) );

    char myString[30] = "";
    ssize_t nbytes=0;

    if ((nbytes = recv(to_server_socket, myString, sizeof(myString), 0 )) < 0)
    {
        perror("recv");
        exit(1);
    }
    myString[nbytes - 1] = '\0';


    printf("Recived String : %s",myString);


}

结果我得到了我的号码,然后是“套接字读取字符串失败”消息。 如果我不做测试,我也没有任何结果

char myString[20] = "";
    recv( to_server_socket, &myString, sizeof( myString), 0 );

【问题讨论】:

  • 能否使用WireShark或其他软件监控网络流量并检查字符串是否正确传递?
  • 使用 java 客户端可以完美运行
  • 您的错误检查对于字符串大小写看起来无效。为什么发送的字符串正好是 30 个字符长?
  • 不要让你的实例引用标签以大写字母开头,这是违反约定的
  • 我用 30 作为最大值

标签: java c sockets


【解决方案1】:

问题出在下面一行:

 char myString[30] = "";

 if( recv( to_server_socket, &myString, sizeof( myString), 0 ) != sizeof( myString ))

您确定从 Java 发送的字符串是 30 个字符吗?在上一行中,您正在检查 recv 的返回值以查看该值是否为 30,可能不是这样。

只需打印 recv 的返回值,看看它是否获取任何数据以及该数据中存在多少个字符。

【讨论】:

  • 不,它是 10 到 20 个字符之间的随机字符串,我把 30 作为最大值
  • 但是,如果是 10 到 20 个字符之间的随机字符串,那么最多只能得到 20 个字符。因此,recv 函数将只接收 20 个字符,因此条件将失败。所以,我想现在,你一定清楚问题所在了。
  • 我尝试了 20,但它不起作用,所以我想尝试 30,因为字符串中的 C 中可能还有其他字符,例如字符串末尾的 \0