0

最近はcソケットプログラミングを勉強しているので、クライアントサーバーモデルの練習用にサンプルを書いています。サーバーに送信するメッセージ データとして構造体を使用し、サーバーがデータを処理します。IOS シミュレーターで実行すると正しいのですが、デバイスでは間違っています。サーバーがデバイス クライアントから受け取る構造データが、クライアント メッセージ データと異なることがわかりました。私の英語がとても下手ですみません。

私の構造コードは次のとおりです。

 typedef struct Message
    {
        char msg[4000];
        char name[256];
        bool isBroadcast;
        bool islogin;
        USER userInfo;
    }__attribute__((packed)) MessageType;

ユーザーコードは:

typedef struct user
{
    int id_number;
    char name[256];
    char password[20];
    char *p_chatlog;
    struct sockaddr user_addr;
    int sock;
} __attribute__((packed)) USER;

送信コードは:

MessageType *loginMsg = (MessageType *)malloc(sizeof(MessageType));
bzero(loginMsg, sizeof(MessageType));
loginMsg->islogin = true;
const char *name_str = [userName.text UTF8String];
memcpy(&(loginMsg->userInfo.name), name_str, strlen(name_str));

const char *password_str = [password.text UTF8String];
memcpy(&(loginMsg->userInfo.password), password_str, strlen(password_str));
write(m_sock, loginMsg, sizeof(MessageType));
free(loginMsg);

サーバー受信コードは read() 関数を使用してから、受信文字を構造体型に変換します。

4

1 に答える 1

1

ネットワークバイトオーダーでデータを送信することをお勧めします。htonl、 htons および ntohl、ntohs システム関数を使用します。デバイスが異なれば、エンディアンも異なる場合があります。また、ネットワーク バイト オーダーであっても、構造体をネットワーク経由で送信するだけではいけません。必要なデータを送信するための単純なプロトコルを考案する方がよいでしょう。これは、より保守しやすく、柔軟性があります。また、要求したすべてのデータが書き込みによって送信されたことを保証することはできません。読み取りと書き込みの両方の戻り結果をチェックして、期待した量であることを確認する必要があります。

ちなみに、iOS 用の POSIX ネットワーク ライブラリは避け、可能な場合はネイティブ実装を使用することをお勧めします。

于 2013-06-19T08:05:05.950 に答える