• 締切済み

write関数でEAGAINのエラー発生 対策方法

現在、私はOS:LINUX 開発環境:QT5.3 を使いシリアル通信を行っています。 そこで質問ですが、シリアル通信でwrite関数を使用しデータの送信を行おうとしていますが 1024バイトのデータを送信しているとき、4回までの送信はエラーがなく成功するのですが、 5回目以降の送信時EAGAIN(リソースが一時的に利用できません)と 出てきてしまいそのあといくら待ってもデータの送信ができない状態となっています 何か対策がありましたらよろしくお願いします。以下が今回プログラムしたソースとなっております。 #include "stdio.h" #include "stdlib.h" #inlclude "strings.h" #include "unistd.h" #include "fcntl.h" #include "cp4141.h" #include "termios.h" #include "error.h" #include "sys/ioctl.h" static int fd; main() { int ret; unsigned long BaudRate = 230400; termios newtio; fd = open("/dev/ttyG0",O_RDWR | O_NOCTTY | O_NONBLOCK); if(fd==-1) { perror(("/dev/ttyG0"); return; } bzero(&newtio, sizeof(newtio)); newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD; newtio.c_iflag = IGNPAR | ICRNL; newtio.c_oflag = 0; newtio.c_lflag = ICANON; tcflush(fd, TCIOFLUSH); tcsetattr(fd, TCSANOW, &newtio); } //画面上のボタンが押されたとき実行される関数 void Button1_Push() { int ret; char buff[1024]; sprintf(buff, "dummy"); ret = write(fd, buff, 1024); if(ret == -1) { perror("send"); return; } } 上記のボタンが押されたときそうしんする処理で5回目に必ずエラーが発生します。 以上よろしくお願いします。

みんなの回答

  • wormhole
  • ベストアンサー率28% (1622/5659)
回答No.1

受信する側は受信してるんでしょうか。 受信する側が受信してなくて送信バッファが溢れてる状態なのでは?

関連するQ&A

  • 2進数でのシリアル通信

    シリアルを用いてデータを伝送するプログラムを作りたいのですが、よく分かりません。 10進数では出来たのですが2進数に変換する際に上手く行きません。 シリアル通信のプログラムとして以下を使用しています。 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <termios.h> #include <fcntl.h> #include <errno.h> #define BAUDRATE B9600 //hentyou-kaisu per second #define BSIZE 64 //byte size #define CR 0x0D // carriage return int fd; //file descriptor 0:H-nyuryoku,1:H-syuturyoku,2;error struct termios otio; int open_serial_port(char *modem_dev) //modem_dev = serial_dev { struct termios ntio; if ((fd = open(modem_dev, O_RDWR | O_NOCTTY)) < 0) { // O_RDWR=read&write O_NOCTTY= perror(modem_dev); exit (1); } tcgetattr(fd, &otio); //tanmatsu-no-now-settei-syutoku memset(&ntio, 0, sizeof(ntio)); ntio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD; ntio.c_cc[VTIME] = 0; //burst-de-datadenso-wo-timeout-surutameno-timer ntio.c_cc[VMIN] = 1; //jyusin-moji-no-min tcflush(fd, TCIFLUSH); // not read data-wo flash tcsetattr(fd, TCSANOW, &ntio); //new-tanmatsu-settei-watasu return (0); } void close_serial_port(void) { tcsetattr(fd, TCSANOW, &otio); //motono-settei-ni-modosu close(fd); } int main(int argc, char **argv) { char *serial_dev; // char buf[BSIZE]; //data-wo-kakikomu-buffa-no-top-address char *buf = (char *)malloc(sizeof(char)*64); char msg[BSIZE]; int i,j; j=0; if (argc != 2) { fprintf(stderr, "usage : %s serial_dev\n", argv[0]); exit (1); } serial_dev = argv[1]; //device to write e.g. /dev/ttyUSB0 memset(buf, '\0', BSIZE); //m byte memory block no set \0=char-gatano-0 memset(msg, '\0', BSIZE); //syokika open_serial_port(serial_dev); i = 0; while (1) { //infinite loop sprintf(buf, "%d,", i); //printf-wo-buf-ni j = strlen(buf); write(fd, buf, j); //write to modem-device printf("%s\n", buf); sleep (2); //read(fd, msg, BSIZE); //printf("%s\n", msg); i++; if (i >= 10) i = 0; } close_serial_port(); free(buf); exit (0); } 2進数変換プログラムは、 #include <stdio.h> #include <stdlib.h> int main(void) { int i, n; int bits[1024]; int digit, amari; printf("10進数: "); scanf("%d", &digit); n=0; while(digit>=1){ amari = digit % 2; /* 配列変数に順番に代入して */ bits[n++] = amari; digit = digit / 2; } /* 逆順に表示している */ for(i=n-1; i>=0; i--){ printf("%d", bits[i]); } printf("\n"); return 0; } この両者をつなぎ合わせたいのですが、どうすればよろしいでしょうか。

  • 低水準ファイル入出力

    openを用いてファイル:"test.dat"を開き、そのファイルにbuffに示すような適当なデータを書き込みたいのですが、 下記の様に記述してコンパイル、実行した結果"test.dat"内には何も記述されていませんでした。 自分でも調べてみたのですがどうしても上手くいかず、この場で質問させて頂きます。 ご指摘の程宜しくお願いします<(_ _)> #include <stdio.h> #include <sys/stat.h> #include <sys/types.h> #include <fcntl.h> int main(void) {  char buff[]={"test123456789"};  int fd;  fd=open("test.dat",O_CREAT,S_IREAD|S_IWRITE);  if(fd==-1)   {    close(fd);    fd=open("test.dat",O_WRONLY);    if(fd == -1)    {      printf("open error <file>");      return 1;    }   }  write(fd,buff,sizeof(buff));  close(fd);  return 1; } ---- 私の環境 ---- Vine Linux 2.6r4

  • C言語のfork()とpipe()の使用方法についてのサンプルを作成し

    C言語のfork()とpipe()の使用方法についてのサンプルを作成していますが、 期待通りの動作をさせる事ができないため、質問させて頂きます。 現在は、aaa.txtの1行目(てすとだよ。)のみ出力されて2行目が出力されません。 (1)実行方法:a.out aaa.txt (2)期待動作:aaa.txt の内容を出力 <aaa.txt> てすとだよ。 pipeだよ。 <ソース> #include <stdio.h> #include <unistd.h> #include <sys/wait.h> #include <stdlib.h> #include <string.h> #define BUFF_SIZE 1024 /* バッファのサイズ1M */ int main(int argc, char **argv) { int pipefd[2]; int p_id; int ret; /* 関数の戻り値 */ int status; FILE *fp; char buff[BUFF_SIZE]; ret = pipe(pipefd) ; /* パイプ生成失敗 */ if(ret == -1) { perror("main"); exit(EXIT_FAILURE); } /* 子プロセス生成 */ p_id = fork(); /* 子プロ生成失敗 */ if(p_id == -1) { perror("main"); exit(EXIT_FAILURE); } if(p_id == 0) { /* 子プロセス側処理 */ printf("子プロ処理開始!!!\n"); /* 使用しないwrite側はクローズ */ close(pipefd[1]); /* パイプから読込む */ while(read(pipefd[0], &buff, BUFF_SIZE) > 0) { fputs(buff, stdout); } close(pipefd[0]); printf("子プロ処理終了!!!\n"); } else { /* 親プロセス側処理 */ printf("親プロ処理開始!!!\n"); /* 使用しないread側はクローズ */ close(pipefd[0]); printf("親プロ:読込ファイル名[%s]\n",*(argv + 1) ); if( (fp = fopen( *(argv + 1), "r" ) ) != NULL) { while(fgets(buff, BUFF_SIZE, fp) != NULL) { printf("パイプに書込む値:%s\n",&buff[0]); /* パイプに書き込む */ write(pipefd[1], buff, strlen(buff) + 1); } fclose(fp); } else { perror("親プロセス "); } close(pipefd[1]); wait(&status); } return EXIT_SUCCESS; }

  • C言語によるBerkeley DB アクセスでエラー

    FreeBSD 6.1でC言語によるプログラムを書いています。 ここでデータベースにBerkeley DBを使用しているのですがputで引数エラーが出ます。 以下テストプログラムです。 #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <limits.h> #include <db.h> #include <fcntl.h> #include <string.h> #include <errno.h> int main() { DB* db; DBT key, val; memset(&key, 0, sizeof(DBT)); memset(&val, 0, sizeof(DBT)); key.data = (char *)"key"; key.size = strlen((char *)key.data); val.data = (char *)"データです。"; val.size = strlen((char *)val.data); if((db = dbopen("test.db", O_CREAT | O_RDWR, 644, DB_BTREE, NULL)) == NULL) { perror("dbopen"); exit(1); } if(db->put(db, &key, &val, R_SETCURSOR) == -1) { perror("put"); exit(1); } if(db->close(db) == -1) { perror("close"); exit(1); } } 結果:put: Invalid argument マニュアルやGoogleのソースコード検索等をして調べてみたのですが、どうしても解決できません。 お分かりになる方、ぜひ御教示お願いします。

  • TCP/IP通信型電話番号検索プログラムを作りたいです。

    TCP/IP通信型電話番号検索プログラムを作りたいです。 クライアントは以下のようで大丈夫みたいなのですが、サーバの方を修正しなければなりません。 この質問で「TCP/IP通信型大文字・小文字変換プログラム」を発見しました。 サーバー側プログラム #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <unistd.h> #include <sys/socket.h> #include <arpa/inet.h> #define SOCK_NAME "./socket" int main() { int i; int fd1, fd2; struct sockaddr_in saddr; struct sockaddr_in caddr; int len; int ret; char buf[1024]; if((fd1 =socket(AF_INET, SOCK_STREAM, 0)) < 0 ){ perror("socket"); exit(1); } memset((char *)&saddr, 0, sizeof(saddr)); saddr.sin_family = AF_INET; saddr.sin_addr.s_addr=INADDR_ANY; saddr.sin_port=htons(1357); unlink(SOCK_NAME); if(bind(fd1, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { perror("bind"); exit(1); } if(listen(fd1,5) < 0 ) { perror("listen"); exit(1); } while(1){ len = sizeof(caddr); if((fd2 = accept(fd1, (struct sockaddr *)&caddr, &len)) < 0){ perror("accept"); exit(1); } fprintf(stderr, "Connection established: socket %d used.\n", fd2); while((ret = read(fd2, buf, 1024)) > 0 ){ fprintf(stderr, "read: &s\n", buf); for(i=0; i<ret; i++) if(islower(buf[i])) buf[i] = toupper(buf[i]); if(isupper(buf[i])) buf[i] = tolower(buf[i]); fprintf(stderr, "write: %s\n", buf); write(fd2, buf, 1024); } close(fd2); } close(fd1); return 0; } 先生によると、クライアントは同じもので良いそうです。 誰か、助けて下さい。

  • TCP/IP通信型大文字・小文字変換プログラム

    TCP/IP通信型大文字・小文字変換プログラムを作りたいです。 しかし、うまく2つのプログラムが接続されません。 恐らく、IPアドレスやホスト名の問題だと思います。 超初心者でそこのところをあまり理解していません。 どなたかプログラムの補足をお願いします。 概要は ・クライアント キーボードから文字列を入力し、サーバーに送信。 サーバーから送信された文字列を画面に出力。 ・サーバー クライアントから送信された文字列に対し、 大文字は小文字に、小文字は大文字に変換して返す。 クライアント側プログラム #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> #define SOCK_NAME "./socket" int main() { struct sockaddr_in saddr; int soc; char buf[1024]; if ( (soc =socket(AF_INET, SOCK_STREAM, 0 ) ) < 0 ) { perror("socket"); exit(1); } memset((char *)&saddr, 0, sizeof(saddr)); saddr.sin_family = AF_INET; saddr.sin_addr.s_addr=inet_addr("192.168.1.1"); saddr.sin_port=htons(1357); if(connect(soc, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { perror("connect"); exit(1); } fprintf(stderr, "Connection established: socket %d used.\n", soc); while(fgets(buf, 1024, stdin)){ if(buf[strlen(buf) -1] == "\n") buf[strlen(buf) -1] = "\0"; write(soc, buf, 1024); read(soc, buf, 1024); fprintf(stdout, "%s\n", buf); } close(soc); return 0; } サーバー側プログラム #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <unistd.h> #include <sys/socket.h> #include <arpa/inet.h> #define SOCK_NAME "./socket" int main() { int i; int fd1, fd2; struct sockaddr_in saddr; struct sockaddr_in caddr; int len; int ret; char buf[1024]; if((fd1 =socket(AF_INET, SOCK_STREAM, 0)) < 0 ){ perror("socket"); exit(1); } memset((char *)&saddr, 0, sizeof(saddr)); saddr.sin_family = AF_INET; saddr.sin_addr.s_addr=INADDR_ANY; saddr.sin_port=htons(1357); unlink(SOCK_NAME); if(bind(fd1, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { perror("bind"); exit(1); } if(listen(fd1,5) < 0 ) { perror("listen"); exit(1); } while(1){ len = sizeof(caddr); if((fd2 = accept(fd1, (struct sockaddr *)&caddr, &len)) < 0){ perror("accept"); exit(1); } fprintf(stderr, "Connection established: socket %d used.\n", fd2); while((ret = read(fd2, buf, 1024)) > 0 ){ fprintf(stderr, "read: &s\n", buf); for(i=0; i<ret; i++) if(islower(buf[i])) buf[i] = toupper(buf[i]); if(isupper(buf[i])) buf[i] = tolower(buf[i]); fprintf(stderr, "write: %s\n", buf); write(fd2, buf, 1024); } close(fd2); } close(fd1); return 0; }

  • 関数でエラー

    #include<stdio.h> int func(int, int); int main() { int a, b, c; a = 10; b = 20; c = func(a, b); printf("%d x %d" = %d\n", a, b, c) return 0; } int func(int a, int b) { int c; c = a * b; return c; } エラーが出てしまうのですが、どうしてエラーが出るのか教えて頂けないでしょうか? エラー一覧です。 ------------------------------------------------------------------------------------------------------------------------------- 配列型 const char[8]を割り当てることはできません。 14行目 ;がreturnの前にありません              16行目 式は変更可能な左辺値である必要があります      14行目 ;が必要です                     16行目 よろしくお願いします。

  • 関数式マクロでエラーです。

    原因と解決方法を教えてください。 御願いします。 ・現象  Solarisでは問題なくコンパイル出来ますが、Linux(以下のバージョン参照)上ではエラーになります。  他の人によるとgcc 2.xでは問題なけれど、gcc 3.x以上ではエラーになると聞きましたが… ・質問  1.コンパイラのバージョン問題ですか?  2.解決するにはパッチが必要ですか?  3.必要だったら、何のパッチが必要ですか?  (ソースの修正なしで解決したいです。) ・エラーメッセージ: define_test.c:38:1: pasting "_test" and "(" does not give a valid preprocessing token Kernel:Red Hat Enterprise Linux AS release 4 (Nahant) Compiler:g++ (GCC) 3.4.3 20041212 (Red Hat 3.4.3-9.EL4) -- 以下 ソース -- #include <stdio.h> #include <stdlib.h> #define SEND4(o, m, l, on_off) o->send_extr_indir(o->_##m##l, on_off) class Define { public: int send_extr_indir(int data1, int data2); int _test(int arg1, int arg2); int test(void); }; int Define::send_extr_indir(int data1, int data2) { printf("data1=%d\n", data1); printf("data2=%d\n", data2); return data1+data2; } int Define::_test(int arg1, int arg2) { return arg1 + arg2; } int Define::test(void) { return SEND4(this, test, (1,2), 5 ); } int main(void) { int result = 0; Define object; result = object.test(); printf("result=%d\n", result); return 0; }

  • mmapで自作cat

    はじめまして。C言語(というかプログラミング自体)まったくの初心者です。 mmapで自作catコマンドを作りたいのですが、 以下のソースコードでコンパイルできたものの、 a.outするとsegmentation faultとなってしまいます。 もしよろしければ何がいけないか、ご指摘いただけると嬉しいです。 1 #include<sys/types.h> 2 #include<sys/stat.h> 3 #include<sys/mman.h> 4 #include<fcntl.h> 5 #include<unistd.h> 6 #include<stdio.h> 7 #include<string.h> 8 9 int main (int argc, char*argv[]){ 10 11 int fd; 12 char *m; 13 int size; 14 15 if(argc < 3){ 16 open(argv[1],O_RDWR); 17 } 18 19 fd = open(argv[1], O_RDWR); 20 if(fd < 0){ 21 printf("error\n"); 22 }else{ 23 fseek(0, 0L, SEEK_END); 24 size = ftell(0); 25 } 26 27 m = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); 28 29 if(m == MAP_FAILED){ 30 printf("error\n"); 31 }else{ 32 write(1,m,strlen(m)); 33 34 close(fd); 35 return 0; 36 } 37 }

  • C言語 エラーチェックについて

    初めまして。分からないところがあったので質問させていただきます。 以下のプログラムは引数から値を取得し、その値で生データの切り出しを 行うプログラムです。 read関数のところなのですが、argv[1]に格納されたファイル(パス名)が0byteでもエラーが出力されずに、コンパイルされてしまいます。 どうすればよいのでしょうか? さらに、上司にreadとwriteにエラーチェックのメッセージをつけろ。と言われたのですが、どうやれば良いのかよく分かりませんでした。if()~とすれば良いのでしょうか?初心者なので分かりにくい質問かと思いますが、どうぞよろしくお願いします。 #pragma warning ( disable : 4996 ) #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <io.h> #include <sys/stat.h> #define ONESEGSIZE 2048 void main ( argc, argv ) int argc; char *argv[]; { int fd, fd2; // ファイルハンドル int segment; // 列数 int raw_n; // 切り出す生データの数 int tviews; // 総ビュー数 int start_view; // 切り出し開始ビュー int size_view; // 切り出しサイズ int pitch_view; // 切り出しピッチ char *Rawdivit; // コマンド char *raw_file; // 生データファイル名 char *outraw_file; // 生データ出力ファイル名 char *mem; // メモリ変数 /* パラメータの個数チェック */ if ( argc != 9 ) { printf( "usage : Rawdivit raw_file outraw_file segment raw_n" " tviews start_view size_view pitch_view \n" ); exit ( 1 ); } /* 引数の取得char型 */ Rawdivit = argv[0]; raw_file = argv[1]; outraw_file = argv[2]; /* 引数の取得int型 */ segment = atoi ( argv[3] ); raw_n = atoi ( argv[4] ); tviews = atoi ( argv[5] ); start_view = atoi ( argv[6] ); size_view = atoi ( argv[7] ); pitch_view = atoi ( argv[8] ); /* 生データファイルオープン */ fd = open ( raw_file, O_RDONLY | O_BINARY ); if ( fd == -1 ) { printf ( "Fileopen error : read\n" ); exit ( -1 ); } /* 生データ読み込み用メモリ確保 */ mem = ( char * ) malloc ( ONESEGSIZE * segment * size_view ); // 単位 = byte if ( mem == NULL ) { printf ( "Memorysecure error\n" ); exit ( -1 ); } /* 切り出し開始位置までファイルポインタをシーク */ lseek ( fd, ONESEGSIZE * segment * start_view, SEEK_SET ); /* 切り出しサイズ分読み込み */ read ( fd, mem, ONESEGSIZE * segment * size_view ); /* 出力ファイルオープン */ fd2 = open ( outraw_file, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, S_IREAD | S_IWRITE ); if ( fd2 == -1 ) { printf ( "Fileopen error : write\n" ); exit ( -1 ); } /* 読み込んだデータを出力ファイルに書き込み */ write ( fd2, mem, ONESEGSIZE * segment * size_view ); /* メモリの開放 */ free ( mem ); /* ファイルクローズ */ close ( fd ); close ( fd2 ); exit ( 0 ); }