C言語初心者です。コードの作り方がわかりません。

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
mame
記事: 2
登録日時: 2年前

C言語初心者です。コードの作り方がわかりません。

#1

投稿記事 by mame » 2年前

先日から少しづつC言語の勉強をしております。
今回は「DATE」という文字を送ると日付が返ってくるような
サーバクライアントのシステムを作成しようと考えているのですが、
C言語の知識がまだ浅いため、うまくコードを作ることができません。

まずサーバ側のコードを作ってみたのですが、コンパイルすらうまくいきません。

コード:

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <time.h>
#include <string.h>

int main(int argc, char *argv[]){
  int srcSocket;
  
  int newsid;
  struct sockaddr_in srcAddr;
  char buf[1024];

    srcAddr.sin_family = AF_INET;
    srcAddr.sin_port=htons(atoi(argv[1]));
    srcAddr.sin_addr.s_addr = INADDR_ANY;

    srcSocket = socket(AF_INET, SOCK_STREAM, 0);
   
    bind(srcSocket, (struct sockaddr *)&srcAddr, sizeof(srcAddr));
    
    listen(srcSocket, 1);

    while(1){
      readline(newsid, buf, 1);
      if (strncmp(buf, "DATE", 4) == 0) {
      	time_t t = time(NULL);
      	sprintf(buf, "現在の時刻は%s です¥r¥n", ctime(&t));
      	response(newsid, buf);
    }	else if (strncmp(buf, "QUIT", 4) == 0) {
    		response(newsid, "+OK¥r¥n");break;
    	} else {
    		response(newsid, "-NGNo such command¥r¥n");
  	}
  }
  return(0);
}
これをコンパイルするとこのようなものが出ます。

fins.c: In function ‘main’:
fins.c:26:7: warning: implicit declaration of function ‘readline’ [-Wimplicit-function-declaration]
26 | readline(newsid, buf, 1);
| ^~~~~~~~
fins.c:30:8: warning: implicit declaration of function ‘response’ [-Wimplicit-function-declaration]
30 | response(newsid, buf);
| ^~~~~~~~
/usr/bin/ld: /tmp/ccwhX99N.o: in function `main':
fins.c:(.text+0xca): undefined reference to `readline'
/usr/bin/ld: fins.c:(.text+0x143): undefined reference to `response'
/usr/bin/ld: fins.c:(.text+0x180): undefined reference to `response'
/usr/bin/ld: fins.c:(.text+0x1b0): undefined reference to `response'
collect2: error: ld returned 1 exit status

この後クライアント側のコードも作成して成功するか試したいのですが、
コードがうまく作れないので教えていただけると幸いです。
よろしくお願いします。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: C言語初心者です。コードの作り方がわかりません。

#2

投稿記事 by みけCAT » 2年前

エラーメッセージの通り、readline 関数と response 関数が宣言も定義もされていないため、エラーになっています。
使用する場所の前で宣言または定義をし、どこか(別の翻訳単位でも可)で定義をしないといけません。

(readline 関数については以下の有名なライブラリ関数もありますが、引数が違うので関係無さそうです)
readline(3) manページ
readline(3): line from user with editing - Linux man page
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

mame
記事: 2
登録日時: 2年前

Re: C言語初心者です。コードの作り方がわかりません。

#3

投稿記事 by mame » 2年前

みけCAT様、返信いただきありがとうございます。
勉強不足で申し訳ありません。

readlineについてはこのように記させていただきました。

コード:

int readline(int fd,char *buf){
	ssize_t num;
	ssize_t cnt=0;
	char *s=buf;
	
	while(1){
		num=recv(fd,buf,1,0);
		if(num==0) break;
		if(num<0){
			perror("Error: send");
			exit(-1);
		}
		cnt++;
		
	if(*buf=='\n'){
		*(buf+1)='\0';
		break;
	}
	buf++;
	}

	printf("%s",s);
	return cnt;
	}
これでreadline関数の方は引数の数などを調整しコンパイルできたのですが、
responseに関しては、sendするためだけの自作関数のため、
どうすれば適解かわかりません。

初歩的なことで申し訳ないのですが教えていただけると幸いです。
よろしくお願いします。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: C言語初心者です。コードの作り方がわかりません。

#4

投稿記事 by みけCAT » 2年前

適解かどうかは一旦置いといて、まずは動くことを目指して実装してみるといいと思います。

また、このreadline関数は最初のコードに合わないようですね。
最初のコードではreadline関数に引数を3個渡していますが、#3のreadline関数の引数は2個しかありません。
また、第1引数の値を使うのであれば、未初期化の自動変数の値(不定) newsid を渡すのはまずいでしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

返信

“C言語何でも質問掲示板” へ戻る