teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

1

sorceを追加しました。

2018/12/04 01:57

投稿

asm9922
asm9922

スコア12

title CHANGED
File without changes
body CHANGED
@@ -15,4 +15,144 @@
15
15
  HTTP/1.1 200 OK
16
16
  Content-Length: 27
17
17
  Content-Type: text/html
18
- Date: Thu Jan 1 00:00:00 JST 2012
18
+ Date: Thu Jan 1 00:00:00 JST 2012
19
+
20
+ ```C言語
21
+ #include <stdio.h>
22
+ #include <string.h>
23
+ #include <stdlib.h>
24
+ #include <unistd.h>
25
+ #include <sys/types.h>
26
+ #include <sys/socket.h>
27
+ #include <netinet/in.h>
28
+ #include <arpa/inet.h>
29
+
30
+ #define SERVER_PORT (80)
31
+
32
+
33
+ int
34
+ main(void) {
35
+ int listen_sockfd;
36
+ int accept_sockfd;
37
+ socklen_t sin_size;
38
+ struct sockaddr_in client;
39
+ struct sockaddr_in serv;
40
+ int retc; // return code from functions
41
+ FILE *fp;
42
+
43
+ int numccr = 0; /* counter for contiguraous '\n' */
44
+ char inchar; /* received (keyboard inputted) char */
45
+
46
+ /* init */
47
+ memset(&client, 0, sizeof(struct sockaddr_in));
48
+ sin_size = sizeof(struct sockaddr_in);
49
+
50
+ /* make TCP socket */
51
+ listen_sockfd = socket(PF_INET, SOCK_STREAM, 0);
52
+ if (listen_sockfd < 0 ) {
53
+ perror("webserver (socket)");
54
+ exit(11);
55
+ }
56
+
57
+ /* bind() */
58
+ memset(&serv, 0, sizeof(struct sockaddr_in));
59
+ serv.sin_family = PF_INET; // IPv4
60
+ serv.sin_addr.s_addr = htonl(INADDR_ANY); // IP address
61
+ serv.sin_port = htons(SERVER_PORT); // port #
62
+ retc = bind(listen_sockfd, (struct sockaddr *)&serv,
63
+ sizeof(struct sockaddr_in));
64
+ if (retc < 0 ) {
65
+ perror("webserver (bind)");
66
+
67
+ close(listen_sockfd);
68
+
69
+ exit(12);
70
+ }
71
+
72
+
73
+ /* listen() */
74
+ retc = listen(listen_sockfd, SOMAXCONN);
75
+ if (retc != 0) {
76
+ perror("webserver (listen)");
77
+ close(listen_sockfd);
78
+ exit(13);
79
+ }
80
+
81
+ /* accept() */
82
+ accept_sockfd = accept(listen_sockfd,
83
+ (struct sockaddr *)&client, &sin_size);
84
+ if (accept_sockfd < 0) {
85
+ perror("webserver (accept)");
86
+
87
+ exit(14);
88
+ }
89
+ close(listen_sockfd);
90
+
91
+ /* use FILE * pointer instead of file descriptor */
92
+ if ((fp = fdopen(accept_sockfd, "r+")) == NULL) {
93
+ perror("webserver (fdopen)");
94
+ exit(15);
95
+ }
96
+
97
+ /*** receive request ***/
98
+ /*
99
+ * (通信回線:TCP port 80)(fp)から1文字ずつ入力⇨モニタ出力
100
+ * '\n'が2個連続したら次へ
101
+ */
102
+ while(1){
103
+ fscanf(fp,"%c", &inchar);
104
+
105
+ if(inchar == '\r'){
106
+ continue;
107
+ }
108
+ fprintf(stderr,"%c", inchar);
109
+
110
+ if(inchar == '\n'){
111
+ ++numccr;
112
+ if(numccr == 2){
113
+ break;
114
+ }
115
+ }
116
+ else{
117
+ numccr = 0;
118
+ }
119
+ }
120
+
121
+ /*** send header, then body ***/
122
+ /*
123
+ * TCP port 80(fp)に以下の6行(サーバ➡クライアントに送られるはずの
124
+ * HTTPストリーム)をただ表示する
125
+ */
126
+
127
+ fprintf(fp,
128
+ "HTTP/1.1 200 OK\n"
129
+ "Content-Length: 27\n"
130
+ "Content-Type: text/html\n"
131
+ "Date: Thu Jan 1 00:00:00 JST 2012\n"
132
+ "\n"
133
+ "<p>My num is 201704198.</p>"
134
+ );
135
+
136
+
137
+ /*** monitor set data ***/
138
+ /*
139
+ * モニタ出力: 標準エラー出力に上と同じものを表示する
140
+ */
141
+ fprintf(stderr,
142
+ "HTTP/1.1 200 OK\n"
143
+ "Content-Length: 27\n"
144
+ "Content-Type: text/html\n"
145
+ "Date: Thu Jan 1 00:00:00 JST 2012\n"
146
+ "\n"
147
+ "<p>My num is 201704198.</p>"
148
+ );
149
+
150
+ /* cleanup */
151
+ fclose(fp);
152
+ close(listen_sockfd);
153
+ close(accept_sockfd);
154
+ fprintf(stderr, "server: exit normally.\n");
155
+ exit(0);
156
+ }
157
+
158
+ ``