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

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

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

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

Q&A

解決済

3回答

1624閲覧

TCPのsendto関数の部分がうまく動きません。

john010

総合スコア9

C

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

0グッド

1クリップ

投稿2021/08/05 07:35

単純なUDPのサーバー,クライアントを実装したくてC言語でコードを途中まで書きました。
内容はClientの方からServerにメッセージを送り、正しく送信されたら"ACK"というメッセージをServerからClientに向けて送信します。
しかし、sendto,recvfromの値がそれぞれ−1となり正しく送信されていません。
udpserver.cのところでstrcpyでbufに"ACK"がしっかり上書きされていることはわかっています。
udpserver.cではメッセージの送信とudpclient.cの受信の部分で、ここからどうコードを書けばいいかわかりません。具体的なコードを教えて下さい。
また望んでいる実行結果はserverの方ではHelloと表示され、clientの方ではACKと表示されることです。

udpserver

1#include <stdio.h> 2#include <stdlib.h> 3#include <unistd.h> 4#include <errno.h> 5#include <string.h> 6#include <sys/types.h> 7#include <sys/socket.h> 8#include <netinet/in.h> 9#include <arpa/inet.h> 10#include <netdb.h> 11 12#define MYPORT "4567" // the port that client will be connecting to 13#define MAXBUFLEN 100 14// get sockaddr, IPv4 or IPv6: 15void *get_in_addr(struct sockaddr *sa) 16{ 17 if (sa->sa_family == AF_INET) { 18 return &(((struct sockaddr_in*)sa)->sin_addr); 19 } 20 return &(((struct sockaddr_in6*)sa)->sin6_addr); 21} 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 strcpy(buf,"ACK"); 71 72 73 //Send client an ACK message 74 if(sendto(sockfd,buf,strlen(buf),0,p->ai_addr,p->ai_addrlen)==-1){ 75 printf("Error\n"); 76 } 77 78 /* 79 unknown code 80 */ 81 82 freeaddrinfo(servinfo); 83 close(sockfd); 84 return 0; 85} 86

udpclient

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

Terminal

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

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

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

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

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

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

guest

回答3

0

ベストアンサー

以下のようにしてください。
updserverのmodifyの個所がポイントです。
updserverのaddの個所はきれいに文字を印字するためのものです。
updclientのaddの個所はきれいに文字を印字するためのものです。

udpserver

C

1#include <stdio.h> 2#include <stdlib.h> 3#include <unistd.h> 4#include <errno.h> 5#include <string.h> 6#include <sys/types.h> 7#include <sys/socket.h> 8#include <netinet/in.h> 9#include <arpa/inet.h> 10#include <netdb.h> 11 12#define MYPORT "4567" // the port that client will be connecting to 13#define MAXBUFLEN 100 14// get sockaddr, IPv4 or IPv6: 15void *get_in_addr(struct sockaddr *sa) 16{ 17 if (sa->sa_family == AF_INET) { 18 return &(((struct sockaddr_in*)sa)->sin_addr); 19 } 20 return &(((struct sockaddr_in6*)sa)->sin6_addr); 21} 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 memset(buf,0x00,MAXBUFLEN); //add 66 if ((numbytes = recvfrom(sockfd, buf, MAXBUFLEN-1 , 0, (struct sockaddr *)&their_addr, &addr_len)) == -1) { 67 perror("recvfrom"); 68 exit(1); 69 } 70 printf("Received from client: %s\n", buf); 71 strcpy(buf,"ACK"); 72 73 74 //Send client an ACK message 75 if(sendto(sockfd,buf,strlen(buf),0,(struct sockaddr *)&their_addr,addr_len)==-1){ //modify 76 printf("Error\n"); 77 } 78 79 /* 80 unknown code 81 */ 82 freeaddrinfo(servinfo); 83 close(sockfd); 84 return 0; 85} 86

updclient

C

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

実行結果
udpserver側
server: waiting for client...
Received from client: Hello

udpclient側
udpclient 127.0.0.1 Hello
Received from server: ACK

投稿2021/08/06 02:41

編集2021/08/06 02:45
tatsu99

総合スコア5438

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

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

0

serverのsendtoの宛先には、recvfromでうけとったtheir_addressを使うべきでは。

投稿2021/08/05 13:20

matukeso

総合スコア1590

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

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

0

送信が出来ていなければ受信出来ないのは当然です。
sendto のパラメータには何を指定しなければならないのかをご確認ください。

投稿2021/08/05 07:45

jimbe

総合スコア12632

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

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

john010

2021/08/05 07:57

sendtoの引数に何かを入れなければいけない事はわかっているのですが、具体的にどのコードを変更すればいいのか教えて下さい。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問