回答編集履歴

1

別解掲載

2022/04/21 07:21

投稿

thkana
thkana

スコア7703

test CHANGED
@@ -1,229 +1,170 @@
1
+ 2022年4月現在で'ESP32 複数 クライアント'でググったらこれがトップでヒットしちゃって...ちょっと恥ずかしいかな。
2
+ 普通にArduinoライブラリでもできちゃったので、一応そちらも載せておきます。二口分の受け方は「ベタ」に書いているので、実際になにかするなら美しくまとめてください。もちろん、動作中にreadStringUntil()とかでブロックしたりしちゃいけませんよ。
3
+ ```Arduino
4
+ #include <WiFi.h>
5
+ WiFiServer server(54321);
6
+
7
+ void setup() {
8
+ Serial.begin(115200);
9
+ WiFi.begin(); //引数省略で最後に接続したAPにつなぎに行く。WiFiの接続とソケットの接続を混同しないようにしましょう。
10
+ while (WiFi.status() != WL_CONNECTED) {
11
+ delay(500);
12
+ }
13
+ Serial.println(WiFi.localIP());
14
+ server.begin();
15
+ }
16
+ WiFiClient client[2];
17
+ String s[2];
18
+ void loop() {
19
+ if( !client[0].connected()){
20
+ client[0]= server.available();
21
+ if(client[0].connected()){
22
+ Serial.println("Connected to 0");
23
+ client[0].println("Connected to 0");
24
+ }
25
+ }else{
26
+ while(client[0].available()){
27
+ char c=client[0].read();
28
+ s[0]+=c;
29
+ if(c=='\n'){
30
+ Serial.println(s[0]);
31
+ client[0].print(s[0]);
32
+ }
33
+ }
34
+ }
35
+ if( !client[1].connected()){
36
+ client[1]= server.available();
37
+ if(client[1].connected()){
38
+ Serial.println("Connected to 1");
39
+ client[1].println("Connected to 1");
40
+ }
41
+ }else{
42
+ while(client[1].available()){
43
+ char c=client[1].read();
44
+ s[1]+=c;
45
+ if(c=='\n'){
46
+ Serial.println(s[1]);
47
+ client[1].print(s[1]);
48
+ }
49
+ }
50
+ }
51
+ }
52
+ ```
53
+ 以下原文
54
+ ---
1
55
  既存のライブラリを真面目に探せばもっといい処理もできそうな気がしますが、見つからなかったので原始的にやってみました。WiFiを繋いだあとはCでソケットを扱う場合の定番にほぼ沿ったものです。
2
56
 
3
-
4
-
5
57
  ```Arduino
6
-
7
58
  #include <sys/select.h>
8
-
9
59
  #include <sys/socket.h>
10
-
11
60
  #include <WiFi.h>
12
61
 
13
-
14
-
15
62
  static const char *WIFI_SSID = "WROOM32";
16
-
17
63
  static const char *WIFI_PASS = "password";
18
-
19
64
  const int port = 1337;
20
65
 
21
-
22
-
23
66
  int fd, maxfd;
24
-
25
67
  int fd2[2] = { -1, -1}; //二口だけ接続をうけつける
26
-
27
68
  struct sockaddr_in addr;
28
-
29
69
  struct sockaddr_in from_addr;
30
-
31
70
  struct timeval tv;
32
71
 
33
-
34
-
35
72
  //サーバー設定-------------------------------------------------
36
-
37
73
  IPAddress ip(192, 168, 1, 10);
38
-
39
74
  //-------------------------------------------------------------
40
75
 
41
-
42
-
43
76
  void setup() {
44
-
45
77
  Serial.begin(115200);
46
-
47
78
  //Wi-Fiアクセスポイント開始--------------------------------------------------------
48
-
49
79
  WiFi.mode(WIFI_AP);
50
-
51
80
  WiFi.softAP(WIFI_SSID, WIFI_PASS);
52
-
53
81
  WiFi.softAPConfig(ip, WiFi.gatewayIP(), WiFi.subnetMask());
54
-
55
82
  //WiFi.softAPConfig(ip, gateway, netmask);
56
83
 
57
-
58
-
59
84
  IPAddress myIP = WiFi.softAPIP();
60
-
61
85
  Serial.println("APStarted. myIP Address:");
62
-
63
86
  Serial.println(myIP);
64
-
65
87
  Serial.print("server Mac Address: ");
66
-
67
88
  Serial.println(WiFi.macAddress());
68
-
69
89
  Serial.print("Subnet Mask: ");
70
-
71
90
  Serial.println(WiFi.subnetMask());
72
-
73
91
  Serial.print("Gateway IP: ");
74
-
75
92
  Serial.println(WiFi.gatewayIP());
76
-
77
93
  //------------------------------------------------------------------------------
78
94
 
79
-
80
-
81
95
  if ( (fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
82
-
83
96
  Serial.println("socket error.");
84
-
85
97
  while (1);
86
-
87
98
  }
88
-
89
99
  addr.sin_family = AF_INET;
90
-
91
100
  addr.sin_port = ntohs(port);
92
-
93
101
  addr.sin_addr.s_addr = INADDR_ANY;
94
-
95
102
  if ( bind( fd, (struct sockaddr *)&addr, sizeof(addr)) < 0 ) {
96
-
97
103
  Serial.println( "bind error" );
98
-
99
104
  while (1);
100
-
101
105
  }
102
-
103
-
104
106
 
105
107
  }
106
108
 
107
109
 
108
-
109
-
110
-
111
110
  void loop() {
112
-
113
111
  if ( listen(fd, 1) < 0) {
114
-
115
112
  Serial.println("listen error.");
116
-
117
113
  }
118
114
 
115
+ fd_set fds;
116
+ FD_ZERO(&fds);
117
+ FD_SET( fd, &fds);
118
+ maxfd = fd;
119
+ for (int i = 0; i < 2; i++) {
120
+ if (fd2[i] != -1) {
121
+ FD_SET(fd2[i], &fds);
122
+ if (fd2[i] > fd) {
123
+ maxfd = fd2[i];
124
+ }
125
+ }
126
+ }
127
+ tv.tv_sec = 0;
128
+ tv.tv_usec = 10000;
129
+ int cnt = select(maxfd + 1, &fds, NULL, NULL, &tv);
130
+ if (cnt <= 0) {
131
+ //error or timeout
132
+ for (int i = 0; i < 2; i++) {
133
+ if (fd2[i] >= 0) {
134
+ //既接続のソケットに対して送信
135
+ char buf[32];
136
+ cnt = sprintf(buf, "To %d %ld\n", fd2[i], millis());
137
+ write(fd2[i], buf, cnt);
138
+ }
139
+ }
140
+ }
141
+ if (FD_ISSET( fd, &fds)) {
142
+ for (int i = 0; i < 2; i++) {
143
+ //接続受付
144
+ if (fd2[i] == -1) {
145
+ socklen_t len = sizeof(struct sockaddr_in);
146
+ if ((fd2[i] = accept(fd, (struct sockaddr *)&from_addr, &len)) < 0) {
147
+ Serial.println("accept error.");
148
+ while (1);
149
+ }
150
+ Serial.println("connect " + String( fd2[i]));
151
+ break;
152
+ }
153
+ }
154
+ }
155
+ for (int i = 0; i < 2; i++) {
156
+ if (fd2[i] != -1 && FD_ISSET(fd2[i], &fds) ) {
157
+ //受信&接続断検出
158
+ char buf[256];
159
+ int rcvCnt = recv(fd2[i], buf, sizeof(buf), 0);
160
+ Serial.println("rcvd:" + String(buf));
161
+ if (rcvCnt < 0) {
162
+ Serial.println("disconnect " + String(fd2[i]));
163
+ close(fd2[i]);
164
+ fd2[i] = -1;
165
+ }
166
+ }
167
+ }
168
+ }
169
+ ```
119
170
 
120
-
121
- fd_set fds;
122
-
123
- FD_ZERO(&fds);
124
-
125
- FD_SET( fd, &fds);
126
-
127
- maxfd = fd;
128
-
129
- for (int i = 0; i < 2; i++) {
130
-
131
- if (fd2[i] != -1) {
132
-
133
- FD_SET(fd2[i], &fds);
134
-
135
- if (fd2[i] > fd) {
136
-
137
- maxfd = fd2[i];
138
-
139
- }
140
-
141
- }
142
-
143
- }
144
-
145
- tv.tv_sec = 0;
146
-
147
- tv.tv_usec = 10000;
148
-
149
- int cnt = select(maxfd + 1, &fds, NULL, NULL, &tv);
150
-
151
- if (cnt <= 0) {
152
-
153
- //error or timeout
154
-
155
- for (int i = 0; i < 2; i++) {
156
-
157
- if (fd2[i] >= 0) {
158
-
159
- //既接続のソケットに対して送信
160
-
161
- char buf[32];
162
-
163
- cnt = sprintf(buf, "To %d %ld\n", fd2[i], millis());
164
-
165
- write(fd2[i], buf, cnt);
166
-
167
- }
168
-
169
- }
170
-
171
- }
172
-
173
- if (FD_ISSET( fd, &fds)) {
174
-
175
- for (int i = 0; i < 2; i++) {
176
-
177
- //接続受付
178
-
179
- if (fd2[i] == -1) {
180
-
181
- socklen_t len = sizeof(struct sockaddr_in);
182
-
183
- if ((fd2[i] = accept(fd, (struct sockaddr *)&from_addr, &len)) < 0) {
184
-
185
- Serial.println("accept error.");
186
-
187
- while (1);
188
-
189
- }
190
-
191
- Serial.println("connect " + String( fd2[i]));
192
-
193
- break;
194
-
195
- }
196
-
197
- }
198
-
199
- }
200
-
201
- for (int i = 0; i < 2; i++) {
202
-
203
- if (fd2[i] != -1 && FD_ISSET(fd2[i], &fds) ) {
204
-
205
- //受信&接続断検出
206
-
207
- char buf[256];
208
-
209
- int rcvCnt = recv(fd2[i], buf, sizeof(buf), 0);
210
-
211
- Serial.println("rcvd:" + String(buf));
212
-
213
- if (rcvCnt < 0) {
214
-
215
- Serial.println("disconnect " + String(fd2[i]));
216
-
217
- close(fd2[i]);
218
-
219
- fd2[i] = -1;
220
-
221
- }
222
-
223
- }
224
-
225
- }
226
-
227
- }
228
-
229
- ```