質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.35%
C

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

Q&A

解決済

1回答

1944閲覧

UDPクライアントの「クライアントにACKメッセージを送信する」部分を実装したいと考えています。

john010

総合スコア9

C

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

0グッド

1クリップ

投稿2021/07/28 06:27

編集2021/07/28 07:18

単純なUDPのサーバー,クライアントを実装したくてC言語でコードを途中まで書きました。clientの方でACKの値が戻るようにしたいですが、ここからどうコードを書けばいいかわかりません。具体的なコードを教えて下さい。

udpserver

1//udpserver.c 2#include <stdio.h> 3#include <stdlib.h> 4#include <unistd.h> 5#include <errno.h> 6#include <string.h> 7#include <sys/types.h> 8#include <sys/socket.h> 9#include <netinet/in.h> 10#include <arpa/inet.h> 11#include <netdb.h> 12 13#define MYPORT "4567" // the port that client will be connecting to 14#define MAXBUFLEN 100 15// get sockaddr, IPv4 or IPv6: 16void *get_in_addr(struct sockaddr *sa) 17{ 18 if (sa->sa_family == AF_INET) { 19 return &(((struct sockaddr_in*)sa)->sin_addr); 20 } 21 return &(((struct sockaddr_in6*)sa)->sin6_addr); 22} 23int main(void) 24{ 25 int sockfd; 26 struct addrinfo hints, *servinfo, *p; 27 int rv; 28 int numbytes; 29 struct sockaddr_storage their_addr; 30 char buf[MAXBUFLEN]; 31 int32_t receivedNumber; 32 socklen_t addr_len; 33 34 memset(&hints, 0, sizeof hints); 35 hints.ai_family = AF_UNSPEC; // set to AF_INET to force IPv4 36 hints.ai_socktype = SOCK_DGRAM; // UDP 37 hints.ai_flags = AI_PASSIVE; // use my IP 38 39 40 if ((rv = getaddrinfo(NULL, MYPORT, &hints, &servinfo)) != 0) { 41 fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); 42 return 1; 43 } 44 // loop through all the results and bind to the first we can 45 for(p = servinfo; p != NULL; p = p->ai_next) { 46 if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) { 47 perror("server: socket"); 48 continue; 49 } 50 if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) { 51 close(sockfd); 52 perror("server: bind"); 53 continue; 54 } 55 break; 56 } 57 if (p == NULL) { 58 fprintf(stderr, "listener: failed to bind socket\n"); 59 exit(1); 60 } 61 printf("server: waiting for client...\n"); 62 addr_len = sizeof their_addr; 63 64 //Receive from client 65 if ((numbytes = recvfrom(sockfd, buf, MAXBUFLEN-1 , 0, (struct sockaddr *)&their_addr, &addr_len)) == -1) { 66 perror("recvfrom"); 67 exit(1); 68 } 69 printf("Received from client: %s\n", buf); 70 71 //Send client an ACK message 72 73 /* 74 Complete this part 75 */ 76ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *their_addr, socklen_t addrlen); 77 78 freeaddrinfo(servinfo); 79 close(sockfd); 80 return 0; 81}

udpclient

1//udpclient.c 2#include <stdio.h> 3#include <stdlib.h> 4#include <unistd.h> 5#include <errno.h> 6#include <string.h> 7#include <sys/types.h> 8#include <sys/socket.h> 9#include <netinet/in.h> 10#include <arpa/inet.h> 11#include <netdb.h> 12 13#define SERVERPORT "4567" // the port that client will be connecting to 14#define MAXBUFLEN 100 15 16int main(int argc, char *argv[]) 17{ 18 int sockfd; 19 struct addrinfo hints, *servinfo, *p; 20 struct sockaddr_storage their_addr; 21 socklen_t addr_len; 22 int rv; 23 int numbytes; 24 char buf[MAXBUFLEN]; 25 26 if (argc != 3) { 27 fprintf(stderr,"usage: talker hostname message\n"); 28 exit(1); 29 } 30 31 memset(&hints, 0, sizeof hints); 32 hints.ai_family = AF_UNSPEC; 33 hints.ai_socktype = SOCK_DGRAM; 34 35 if ((rv = getaddrinfo(argv[1], SERVERPORT, &hints, &servinfo)) != 0) { 36 fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); 37 return 1; 38 } 39 // loop through all the results and make a socket 40 for(p = servinfo; p != NULL; p = p->ai_next) { 41 if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) { 42 perror("talker: socket"); 43 continue; 44 } 45 break; 46 } 47 if (p == NULL) { 48 fprintf(stderr, "talker: failed to create socket\n"); 49 return 2; 50 } 51 52 // Send to server 53 if ((numbytes = sendto(sockfd, argv[2], strlen(argv[2]), 0, p->ai_addr, p->ai_addrlen)) == -1) { 54 perror("client: sendto"); 55 exit(1); 56 } 57 58 //Receive from server 59 ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const 60struct sockaddr *dest_addr, socklen_t addrlen); 61 /* 62 Complete this part 63 */ 64 65 printf("Received from server: %s\n", buf); 66 67 freeaddrinfo(servinfo); 68 close(sockfd); 69 70 return 0; 71}

現在の実行結果

terminal

1gcc udpserver.c 2./a.out 3server: waiting for client... 4Received from client: Hello 5 6 7gcc udpclient.c 8 ./a.out 127.0.0.1 Hello 9Received from server: �*��z```

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

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

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

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

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

guest

回答1

0

ベストアンサー

Cは全く分かりませんけど、UDPにACKは出てきません
3wayハンドシェイクを実装したいならTCPだし、その際使うのはデータグラムじゃなくてソケットストリームです
CだとSOCK_STREAMのようですね

なのでまずはUDPを実装したいのかTCPを実装したいのかを明確にしましょう

投稿2021/07/28 06:45

hentaiman

総合スコア6426

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

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

dodox86

2021/07/28 07:45

質問者さんは「ACK」と書いていますが、もしかしたら単に送り返す何らかのパケット、送信データを「ACK」と勝手に呼んでいるのかもしれませんね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問