🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

1回答

1403閲覧

XMODEM送信プログラムのパケット生成がわからない

koukouk

総合スコア11

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

1クリップ

投稿2020/11/23 11:11

前提・実現したいこと

学校の課題で困っているので助けてください。
XMODEMの送信プログラムを作成する課題で、パケット生成で躓いています。235行目でdataSize = ReadDataFromFile(fp, &packet[3], DATA_SIZE, 10);とあり。これでファイルから最大DATA_SIZEバイト読み込むとするのであればpacket[3]=dataSizeとすればpacket[3],packet[4],packet[5]にファイルから読み込んだデータが代入されるのでは無いかと思いました。しかし、実際に通信させてみると受信側の端末でなにも変化が起きず失敗に終わりました。
もう何が何だかわからず、心が折れそうです。このサイトが最後の頼みの綱です。どうかご回答お願いします。
厳しいお言葉は投げかけないでください。勉強不足なのは重々承知の上です。

発生している問題・エラーメッセージ

expected identifier or ‘(’ before ‘}’ token
}

該当のソースコード

#include <sys/types.h>
#include <sys/stat.h>
#include <termios.h>
#include <sys/file.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <sys/time.h>

#define SOH 0x01
#define EOT 0x04
#define ACK 0x06
#define NAK 0x15
#define CAN 0x18
#define SUB 0x1a

#define DATA_SIZE 3
#define TIMEOUT 10

enum States {
NAKReceived, /NAK受信/
SamePacket10Sent, /同一パケットを10回送信/
ACKReceived, /ACK受信/
CAN2Received, /2連続CAN受信/
AllSent, /全パケット送信/
Continue, /ループ周回/
TimeOut /タイムアウト/
};

unsigned char CheckSum(unsigned char *p, size_t size);

/*** 時刻測定:オマジナイ ***/
double GettimeofdaySec();

int Receive(int fd, unsigned char *receiveData, int dataSize, int time);

int Send(int fd, unsigned char sendData, int time);

int ReadDataFromFile(FILE *fp, unsigned char *characterPosition, int readSize, int number);

void printState(enum States);

/*** 初期設定 オマジナイ***/
int Initialize(int *pfd,
FILE **pfp,
char *filename,
double *startTime,
struct termios *pold_tio,
struct termios *pnew_tio);

enum States InitReceive(int fd);

enum States MidState(int fd);

void EndByCAN2Received(int fd, FILE *fp, struct termios *pold_tio);

int EndByTimeOut(int fd, FILE *fp, struct termios *pold_tio);

int EndByAllSent(int *pfd,
FILE *fp,
double startTime,
int packetNumber,
struct termios *pold_tio);

void EndBySamePacket10Sent(int fd, FILE *fp, struct termios *pold_tio);

int End(int fd, FILE *fp, struct termios *pold_tio);

void PrintPacketInfo(double startTime, int packetNumber);

int main(int argc, char **argv) {
int fd;/デバイス識別のためのファイルデスクリプタ/
struct termios old_tio, new_tio;/シリアルデバイス設定/
FILE *fp;/ファイル読込のためのファイル型へのポインタ/
char *filename = argv[1];/送信ファイル名/
int dataSize;/ファイルから読み込んだバイト数/

unsigned char packet[DATA_SIZE+4];/パケット/
unsigned char packetIndex = 0;/パケット番号(1バイト)/
int packetNumber = 0;/パケット番号(int型)/
int SamePacketSentTimes;/同一パケット送信回数/

double startTime;/通信開始時刻(通信時間計測に使用)/

int i;

enum States state;/状態/

/初期設定/
if(Initialize(&fd,
&fp,
filename,
&startTime,
&old_tio,
&new_tio)){
printf("Init Error\n");
exit(1);
}

/初めのNAK受信を試みて状態を獲得する。/
state=InitReceive(fd);
if(/ここに何か書く/state==NAKReceived){/NAK受信したときの処理/
while(1){/ファイルから読込、パケット送信とその応答処理/
/ファイルから最大DATA_SIZEバイト読込;/
dataSize = ReadDataFromFile(fp, &packet[3], DATA_SIZE, 10);
if(dataSize<0){
perror("file read failed\n");
return -1;
}

if(dataSize==0){ state=AllSent; break; } else if(dataSize==1){ dataSize=dataSize+2*SUB; } else if(dataSize==2){ dataSize=dataSize+SUB; } packetIndex++; packetNumber++; /**パケット生成**/ /***ここに何か書く***/ packet[0]=SOH; packet[1]=packetIndex; packet[2]=0xff-packetIndex; packet[3]=dataSize; packet[6]=CheckSum(packet+3,DATA_SIZE); /*同一パケット送信回数リセット*/ /***ここに何か書く***/ SamePacketSentTimes=0; while(1){ if(SamePacketSentTimes>10){ state=SamePacket10Sent; break; } Send(fd,dataSize,60); SamePacketSentTimes++; state=MidState(fd); if(state!=NAKReceived && state!=TimeOut){ break; } }/*while(1) if(state!=ACKReceived){ break; } }/*while(1)ファイルから読込、パケット送信とその応答処理*/

}/if(state==NAK受信)/
/**状態に応じて、関数 */
/*EndByCAN2Received(fd, fp, &old_tio)); */
/*EndByTimeOut(fd, fp, &old_tio); */
/EndByAllSent(&fd, fp, startTime, packetNumber, &old_tio);/
/*EndBySamePacket10Sent(fd, fp, &old_tio); */
/*を呼び出すようにswitch文を書く **/
/ここに何か書く/
switch(state){
case CAN2Received:
EndByCAN2Received(fd, fp, &old_tio);
break;

case TimeOut: EndByTimeOut(fd, fp, &old_tio); break; case AllSent: EndByAllSent(&fd, fp, startTime, packetNumber, &old_tio); break; case SamePacket10Sent: EndBySamePacket10Sent(fd, fp, &old_tio); break; }

return 0;
}
}

/初期設定 オマジナイ/
int Initialize(int *pfd,
FILE **pfp,
char *filename,
double *startTime,
struct termios *pold_tio,
struct termios *pnew_tio){
int state;
int full_data_size;
int blockSize;

/* デバイスのオープン */

/* 読み書き用 (O_RDWR) で開く */
if((*pfd = open("/dev/tnt0", O_RDWR)) < 0) {
perror("open of /dev/tnt0 failed");
return 1;
}

/* 現在のシリアルポートの設定を退避させる */
if((state = tcgetattr(pfd, pold_tio)) < 0) {
perror("tcgetatrr failed");
return 1;
}
/
新しいポートの設定の構造体をクリア */
memset(pnew_tio, 0, sizeof(*pnew_tio));

/* パラメータの設定 */

/* フレームエラーおよびパリティエラーを無視する /
pnew_tio->c_iflag = IGNPAR;
/
rawモード(入力したキーをそのまま前処理せずに渡す /
pnew_tio->c_oflag = 0;
/
非カノニカル入力(read毎に決まった数の文字を扱う) /
pnew_tio->c_lflag = 0;
/
ボーレート(B9600) :9600Bps
文字サイズ(CS8) : 8bit
受信を有効にする(CREAD)
モデムの状態信号を無視する(CLOCAL) */
pnew_tio->c_cflag = ( B9600 | CS8 | CREAD | CLOCAL);

/* ノンブロッキングモード /
pnew_tio->c_cc[VMIN] = 0;
/
キャラクタ間タイマを1[sec]に設定 */
pnew_tio->c_cc[VTIME] = TIMEOUT;

/* ポートのクリア */
if((state = tcflush(*pfd, TCIFLUSH)) < 0 ) {
perror("tcflush failed");
return 1;

}

/* 以上の設定を反映させるために"TCSANOW"を行なう */
if(tcsetattr(*pfd, TCSANOW, pnew_tio) < 0) {
perror("tscsetattr (TCSANOW) failed");
return 1;
}

/* 送信ファイルのオープン */
if((*pfp = fopen(filename, "rb")) == NULL) {
perror("file open failed");
return 1;
}
fseek(*pfp, 0, SEEK_END);
full_data_size = ftell(*pfp);
blockSize = (full_data_size + (DATA_SIZE - 1)) / DATA_SIZE;
fseek(*pfp, 0, SEEK_SET);
printf("Sending %s, %d blocks: Give your local XMODEM receive command now.\n", filename, blockSize);
*startTime = GettimeofdaySec();

return 0;
}

enum States InitReceive(int fd){
enum States state;
unsigned char c;

while(1){
if(!Receive(fd, &c, 1, 60)){

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

y_waiwai

2020/11/23 11:21

このままではコードが読みづらいので、質問を編集し、<code>ボタンを押し、出てくる’’’の枠の中にコードを貼り付けてください
y_waiwai

2020/11/23 11:26

んで、提示されてるエラーメッセージはコンパイルエラーと思いますが、 これがでていたら実行ファイルができないと思うんですが、どうやって実行させてるんでしょうか
guest

回答1

0

ベストアンサー

xmodemなんてもうすっかり忘れましたけど...

235行目で

少なくとも貼り付けてあるソースでは #include <sys/types.h>を1行目として
235行目は
if(tcsetattr(*pfd, TCSANOW, pnew_tio) < 0) {
です。その近辺に dataSize = ReadDataFromFile(... という内容のものはありません。
質問の文章と対応していないソースコードということでしょうか。それでは何も言えません。

packet[3]=dataSizeとすれば

packet[3]の内容はプログラムの動作に関係ないのでは。で、ありがちなパターンから言えば、datasizeはファイルから読みだしたデータサイズが入っているのではないのですか?

packet[3],packet[4],packet[5]にファイルから読み込んだデータが代入されるのでは無いかと思いました。

思うのではなく、ReadDataFromFile関数の定義を確認しましょう。ReadDataFromFile関数が示されていないので、こちらではなにも言えません。

しかし、実際に通信させてみると受信側の端末でなにも変化が起きず失敗に終わりました。

基本的な通信は出来ているのですか? ファイルの読み出しとは別のところに原因がある気配が濃厚に思えます。

投稿2020/11/23 12:08

thkana

総合スコア7703

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問