0

この質問がすでに聞こえている場合は申し訳ありません-見つからなかった...だから私はタイマーを持っています:

bzero(&rtc_act, sizeof(struct sigaction));
rtc_act.sa_handler = &rtc_handler;
sigaction(SIGALRM, &rtc_act, NULL);

rtc_timer.it_interval.tv_sec = SETTIMER_INTERVAL;
rtc_timer.it_interval.tv_usec = 0;
rtc_timer.it_value.tv_sec = SETTIMER_VALUE;
rtc_timer.it_value.tv_usec = 0;

if (setitimer(ITIMER_REAL, &rtc_timer, NULL))
{
    printf(MSG_ERR_SETTIMER_FAIL);
    retval = RETURN_ERR_SETTIMER;
} /* if (setitimer(ITIMER_REAL, &rtc_timer, NULL)) */

また、ソケットをブロックしました:

if ((modbus_socket = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
    retval = RETURN_ERR_SOCKET_OPEN;
    perror(MSG_ERR_OPEN_SOCKET);
    return retval;
} /* if (modbus_socket = socket(AF_INET, SOCK_STREAM, 0) < 0) */

setsockopt(modbus_socket, SOL_SOCKET, SO_REUSEADDR, (const void*)&optval , sizeof(unsigned int));

bzero((char*)&serv_addr, sizeof(serv_addr));

serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons((unsigned short)ZK91_TCP_PORT_NUMBER);

if (bind(modbus_socket, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0)
{
    perror(MSG_ERR_BIND_SOCKET);
    retval = RETURN_ERR_SOCKET_OPEN;
    return retval;
} /* if (bind(modbus_socket, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) */

if (listen(modbus_socket, TCP_CLIENTS_COUNT) < 0)
{
    perror(MSG_ERR_LISTEN_SOCKET);
    retval = RETURN_ERR_SOCKET_LISTEN;
    return retval;
} /* if (listen(parentfd, TCP_CLIENTS_COUNT) < 0) */

select() を使用しようとすると

    FD_ZERO(&fds);
    FD_SET(modbus_socket, &fds);
    FD_SET(can_file, &fds);
    FD_SET(modbus_file, &fds);

    select(modbus_file + 1, &fds, NULL, NULL, &tv);

実際のデータは利用できませんでしたが、select() のアクティベーションを数秒で取得しました。

この「接続」を処理しようとすると、次のようになります。

new_socket = accept (modbus_socket, (struct sockaddr *) & client_addr, & client_len);

次に、プログラムがクラッシュし、画面に10文字が表示され、メモリ領域が表示されます。

ネットが来る(私のメッセージ)

������硨���L�</p>

uclinux#

タイマーを初期化しないと、すべてが正しく機能しますが、タイマーでは拒否できません。

その理由は何でしょうか?

ありがとうございました。

4

2 に答える 2

0

select()返品後、返品理由を確認する必要があります。チェックせずに、「ソケットの読み取り準備ができました」と言っていると仮定することはできません。

チェックはFD_ISSET()マクロを使用して行われ、ソケット ファイル記述子がまだ読み取り準備完了セットにあるかどうかを確認します。

select()が中断されて戻ってきた場合も、 に設定errnoされEINTR、-1 が返されます。通常は 3 つの入力セットのセット記述子の数を返すため、戻り値も確認する必要があります。が 0 より大きい値を返さFD_ISSET()ない限り、呼び出しを開始する必要はありません。select()

于 2013-07-08T12:07:47.423 に答える