質問編集履歴

1

コードがクライアント側でした申し訳ありません

2019/06/26 05:34

投稿

akiya_0608
akiya_0608

スコア14

test CHANGED
File without changes
test CHANGED
@@ -16,85 +16,275 @@
16
16
 
17
17
  class Program
18
18
 
19
+ {
20
+
21
+ static void Main(string[] args)
22
+
23
+ {
24
+
25
+ //Server
26
+
27
+ BaseServer listener = new BaseServer();
28
+
29
+ listener.Init("127.0.0.1", 12345);
30
+
31
+ var task = listener.StartAccept();
32
+
33
+
34
+
35
+ while (true)
36
+
37
+ {
38
+
39
+ listener.BeginUpdate();
40
+
41
+
42
+
43
+ if (listener.clientList.Count > 0)
44
+
45
+ {
46
+
47
+ foreach (TcpRecvServer client in listener.clientList)
48
+
49
+ {
50
+
51
+ while (client.RecvDataListCount() > 0)
52
+
53
+ {
54
+
55
+ byte[] data = client.GetRecvDataList();
56
+
57
+ if(client.Send(data, data.Length)<0)
58
+
59
+ {
60
+
61
+ break;
62
+
63
+ }
64
+
65
+ Console.WriteLine("data合計={0}", client.RecvDataListCount());
66
+
67
+ }
68
+
69
+ }
70
+
71
+ }
72
+
73
+
74
+
75
+ listener.EndUpdate();
76
+
77
+ }
78
+
79
+
80
+
81
+ }
82
+
83
+
84
+
85
+ }
86
+
87
+ class TcpRecvServer
88
+
19
89
  {
20
90
 
21
- //====================================================
22
-
23
- //Client
24
-
25
- //====================================================
26
-
27
-
28
-
29
- static void Main(string[] args)
30
-
31
- {
32
-
33
- Console.WriteLine("入力してください");
34
-
35
- string sendMsg = Console.ReadLine();
36
-
37
-
38
-
39
- //ipアドレスとポート番号設定
40
-
41
- string ipOrHost = "127.0.0.1";
42
-
43
- int port = 12345;
44
-
45
-
46
-
47
- //sendData
48
-
49
- System.Text.Encoding enc = System.Text.Encoding.UTF8;
50
-
51
- byte[] body = enc.GetBytes(sendMsg);
52
-
53
-
54
-
55
- //通信
56
-
57
- BaseSocket sock = new BaseSocket();
58
-
59
- sock.Init(ipOrHost, port);
60
-
61
- sock.StartRecvThread(); //非同期通信Recv
62
-
63
-
64
-
65
-
66
-
67
-
68
-
69
-
70
-
71
- while (true)
72
-
73
- {
74
-
75
- sock.Send(body, body.Length);
76
-
77
- sock.Update();
78
-
79
- while (sock.RecvDataSize() > 0)
80
-
81
- {
82
-
83
- byte[] data = sock.GetRecvData();
84
-
85
- string text = System.Text.Encoding.UTF8.GetString(data);
86
-
87
-
88
-
89
- Console.WriteLine("recvDataSize={0},data={1}", data.Length, text);
90
-
91
- }
92
-
93
- }
94
-
95
-
96
-
97
- }
91
+ public const int BUFSIZE = 2048;
92
+
93
+ object lockObj = new object();
94
+
95
+ public Socket socket { get; }
96
+
97
+ public byte[] ReceiveBuffer;
98
+
99
+ public List<byte> recvTempDataList = new List<byte>();
100
+
101
+ public List<byte[]> recvDataList = new List<byte[]>();
102
+
103
+ public bool deleteFlg { get; private set; } = false;
104
+
105
+ public bool threadDeleteFlg { get; private set; } = false;
106
+
107
+ public TcpRecvServer(Socket _socket)
108
+
109
+ {
110
+
111
+ socket = _socket;
112
+
113
+ ReceiveBuffer = new byte[BUFSIZE];
114
+
115
+ }
116
+
117
+ public byte[] GetRecvDataList()
118
+
119
+ {
120
+
121
+ byte[] returnData;
122
+
123
+ lock (lockObj)
124
+
125
+ {
126
+
127
+ returnData = recvDataList[0];
128
+
129
+ recvDataList.RemoveAt(0);
130
+
131
+ }
132
+
133
+ return returnData;
134
+
135
+ }
136
+
137
+
138
+
139
+ public void AddRecvDateList(byte[] _data)
140
+
141
+ {
142
+
143
+ lock (lockObj)
144
+
145
+ {
146
+
147
+ recvDataList.Add(_data);
148
+
149
+ }
150
+
151
+ }
152
+
153
+
154
+
155
+ public int RecvDataListCount()
156
+
157
+ {
158
+
159
+ int count;
160
+
161
+ lock (lockObj)
162
+
163
+ {
164
+
165
+ count= recvDataList.Count;
166
+
167
+ }
168
+
169
+ return count;
170
+
171
+ }
172
+
173
+
174
+
175
+
176
+
177
+ public int Send(byte[] _sendData, int _dataSize)
178
+
179
+ {
180
+
181
+ int sendSize=-1;
182
+
183
+
184
+
185
+ byte[] sendHeader;
186
+
187
+
188
+
189
+ //header設定
190
+
191
+ sendHeader = BitConverter.GetBytes(_dataSize);
192
+
193
+ //sendBytes作成
194
+
195
+ byte[] sendBytes = new byte[sendHeader.Length + _dataSize];
196
+
197
+ sendHeader.CopyTo(sendBytes, 0);
198
+
199
+ _sendData.CopyTo(sendBytes, sendHeader.Length);
200
+
201
+
202
+
203
+ try
204
+
205
+ {
206
+
207
+ if (socket.Connected)
208
+
209
+ {
210
+
211
+ sendSize=socket.Send(sendBytes, sendBytes.Length, 0);
212
+
213
+ }
214
+
215
+ else
216
+
217
+ {
218
+
219
+ Console.WriteLine("sendError");
220
+
221
+ }
222
+
223
+ }
224
+
225
+ catch(System.ObjectDisposedException)
226
+
227
+ {
228
+
229
+ //閉じた時
230
+
231
+ /*
232
+
233
+ System.Console.WriteLine("閉じました。");
234
+
235
+ this.OnDeleteFlg();
236
+
237
+ */
238
+
239
+ }
240
+
241
+ catch (SocketException e)
242
+
243
+ {
244
+
245
+ Console.WriteLine("ソケットが切断されています。");
246
+
247
+ Console.WriteLine(e);
248
+
249
+ }
250
+
251
+
252
+
253
+ return sendSize;
254
+
255
+ }
256
+
257
+
258
+
259
+ public void OnDeleteFlg()
260
+
261
+ {
262
+
263
+ lock (lockObj)
264
+
265
+ {
266
+
267
+ deleteFlg = true;
268
+
269
+ }
270
+
271
+ }
272
+
273
+ public void OnThreadDeleteFlg()
274
+
275
+ {
276
+
277
+ lock (lockObj)
278
+
279
+ {
280
+
281
+ deleteFlg = true;
282
+
283
+ }
284
+
285
+ }
286
+
287
+
98
288
 
99
289
  }
100
290
 
@@ -102,235 +292,141 @@
102
292
 
103
293
 
104
294
 
105
-
106
-
107
-
108
-
109
-
110
-
111
- class BaseSocket
295
+ class BaseServer
112
296
 
113
297
  {
114
298
 
115
- private List<byte> recvTempDataList = new List<byte>();
116
-
117
- private List<byte[]> recvDataList=new List<byte[]>();
118
-
119
- //ソケット作成
120
-
121
- private System.Net.Sockets.TcpClient tcp;
122
-
123
- private System.Net.Sockets.NetworkStream ns;
124
-
125
- private Object lockObject = new Object();
126
-
127
- private bool deleteFlg = false;
128
-
129
-
130
-
131
- public BaseSocket() { }
132
-
133
-
134
-
135
- ~BaseSocket() { Close(); }
136
-
137
-
138
-
139
- public void Init(string _ipAddr, int _port)
140
-
141
- {
142
-
143
- tcp = new System.Net.Sockets.TcpClient(_ipAddr, _port);
144
-
145
- //メッセージ
146
-
147
- Console.WriteLine("サーバー({0}:{1})と接続しました({2}:{3})。", ((System.Net.IPEndPoint)tcp.Client.RemoteEndPoint).Address,
148
-
149
- ((System.Net.IPEndPoint)tcp.Client.RemoteEndPoint).Port,
150
-
151
- ((System.Net.IPEndPoint)tcp.Client.LocalEndPoint).Address,
152
-
153
- ((System.Net.IPEndPoint)tcp.Client.LocalEndPoint).Port);
154
-
155
- //通信設定
156
-
157
- ns = tcp.GetStream();
158
-
159
- ns.ReadTimeout = 10000;
160
-
161
- ns.WriteTimeout = 10000;
162
-
163
- }
164
-
165
-
166
-
167
- public void Send(byte[] _sendData, int _dataSize)
168
-
169
- {
170
-
171
- byte[] sendHeader;
172
-
173
-
174
-
175
- //header設定
176
-
177
- sendHeader = BitConverter.GetBytes(_dataSize);
178
-
179
- //sendBytes作成
180
-
181
- byte[] sendBytes = new byte[sendHeader.Length + _dataSize];
182
-
183
- sendHeader.CopyTo(sendBytes, 0);
184
-
185
- _sendData.CopyTo(sendBytes, sendHeader.Length);
186
-
187
-
188
-
189
- //send
190
-
191
- ns.Write(sendBytes, 0, sendBytes.Length);
192
-
193
-
194
-
195
- }
196
-
197
- public void Update()
198
-
199
- {
200
-
201
- Routine();
202
-
203
- }
204
-
205
- public void Close()
206
-
207
- {
208
-
209
- deleteFlg = true;
210
-
211
- ns.Close();
212
-
213
- tcp.Close();
214
-
215
- }
216
-
217
-
218
-
219
- private void Routine()
220
-
221
- {
222
-
223
- lock (lockObject)
224
-
225
- {
226
-
227
- while (recvTempDataList.Count > sizeof(int))
228
-
229
- {
230
-
231
- int byteSize = (int)recvTempDataList[0];
232
-
233
- Console.WriteLine("Routine size={0}\n", byteSize);
234
-
235
- if (recvTempDataList.Count > byteSize+sizeof(int))
299
+ public List<TcpRecvServer> clientList { get;} = new List<TcpRecvServer>();
300
+
301
+ private List<TcpRecvServer> addClientList = new List<TcpRecvServer>();
302
+
303
+ private readonly object lockObj=new Object();
304
+
305
+ Socket listener;
306
+
307
+
308
+
309
+ public BaseServer() { }
310
+
311
+
312
+
313
+
314
+
315
+ public void BeginUpdate()
316
+
317
+ {
318
+
319
+ //addClientListのための排他制御
320
+
321
+ lock (lockObj)
322
+
323
+ {
324
+
325
+ if (addClientList.Count > 0)
326
+
327
+ {
328
+
329
+ clientList.AddRange(addClientList);
330
+
331
+ addClientList = new List<TcpRecvServer>();
332
+
333
+ }
334
+
335
+ }
336
+
337
+ }
338
+
339
+
340
+
341
+ public void EndUpdate()
342
+
343
+ {
344
+
345
+ if (clientList.Count <= 0) return;
346
+
347
+
348
+
349
+ List<TcpRecvServer> deleteList = new List<TcpRecvServer>();
350
+
351
+ foreach (TcpRecvServer client in clientList)
352
+
353
+ {
354
+
355
+ if (client.deleteFlg == true)
356
+
357
+ {
358
+
359
+ deleteList.Add(client);
360
+
361
+ }
362
+
363
+ }
364
+
365
+ foreach (TcpRecvServer client in deleteList)
366
+
367
+ {
368
+
369
+ clientList.Remove(client);
370
+
371
+ }
372
+
373
+ }
374
+
375
+ public void Init(string _ip, int _port)
376
+
377
+ {
378
+
379
+ //ListenするIPアドレス
380
+
381
+ IPAddress ipAdd = IPAddress.Parse(_ip);
382
+
383
+
384
+
385
+ //TcpListenerオブジェクトを作成する
386
+
387
+ IPEndPoint ipe = new IPEndPoint(ipAdd, _port);
388
+
389
+ listener = new Socket(ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
390
+
391
+ listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
392
+
393
+ listener.Bind(ipe);
394
+
395
+ listener.Listen(1000);
396
+
397
+
398
+
399
+ }
400
+
401
+
402
+
403
+ public async Task StartAccept()
404
+
405
+ {
406
+
407
+ await Task.Run(() =>
408
+
409
+ {
410
+
411
+ while (true)
412
+
413
+ {
414
+
415
+ TcpRecvServer temp =new TcpRecvServer(listener.Accept());
416
+
417
+ lock (lockObj)
236
418
 
237
419
  {
238
420
 
239
- byte[] addData;
240
-
241
- addData = recvTempDataList.GetRange(sizeof(int), byteSize).ToArray();
242
-
243
- recvDataList.Add(addData);
421
+ addClientList.Add(temp);
244
-
422
+
245
- recvTempDataList.RemoveRange(0, sizeof(int) + byteSize);
423
+ Console.WriteLine("接続あり");
246
424
 
247
425
  }
248
426
 
249
- else
250
-
251
- {
252
-
253
- return;
427
+ StartReceive(temp);
254
-
428
+
255
- }
429
+ }
256
-
257
- }
258
-
259
- }
260
-
261
- }
262
-
263
-
264
-
265
- public void Recv()
266
-
267
- {
268
-
269
- while (true)
270
-
271
- {
272
-
273
- if (deleteFlg) { break; }
274
-
275
- byte[] resBytes = new byte[1024];
276
-
277
- int resSize = -1;
278
-
279
- resSize = ns.Read(resBytes, 0, resBytes.Length);
280
-
281
- if (resSize == 0)
282
-
283
- {
284
-
285
- Console.WriteLine("サーバーが切断しました。");
286
-
287
- deleteFlg = true;
288
-
289
- }
290
-
291
- else if (resSize > 0)
292
-
293
- {
294
-
295
- Array.Resize(ref resBytes, resSize);
296
-
297
- lock (lockObject)
298
-
299
- {
300
-
301
- recvTempDataList.AddRange(resBytes);
302
-
303
- }
304
-
305
- Console.WriteLine("recvSize={0},recvDataListSize={1}\n", resSize, recvTempDataList.Count);
306
-
307
- }
308
-
309
- }
310
-
311
- }
312
-
313
-
314
-
315
- public int RecvDataSize()
316
-
317
- {
318
-
319
- return recvDataList.Count;
320
-
321
- }
322
-
323
-
324
-
325
- public async void StartRecvThread()
326
-
327
- {
328
-
329
- await Task.Run(() =>
330
-
331
- {
332
-
333
- this.Recv();
334
430
 
335
431
  });
336
432
 
@@ -338,24 +434,172 @@
338
434
 
339
435
 
340
436
 
437
+
438
+
439
+ //===========================================================================
440
+
441
+ //recv関係
442
+
443
+ //===========================================================================
444
+
445
+ //データ受信スタート
446
+
341
- public byte[] GetRecvData()
447
+ private static void StartReceive(TcpRecvServer _server)
342
-
448
+
343
- {
449
+ {
450
+
344
-
451
+ //非同期受信を開始
452
+
453
+ _server.socket.BeginReceive(_server.ReceiveBuffer,
454
+
455
+ 0,
456
+
345
- byte[] returnData;
457
+ _server.ReceiveBuffer.Length,
458
+
346
-
459
+ System.Net.Sockets.SocketFlags.None,
460
+
347
- returnData = recvDataList[0];
461
+ new System.AsyncCallback(ReceiveDataCallback),
348
-
349
- recvDataList.RemoveAt(0);
462
+
350
-
351
- return returnData;
463
+ _server);
352
-
464
+
353
- }
465
+ }
466
+
467
+
468
+
469
+
470
+
471
+ //BeginReceiveのコールバック
472
+
473
+ private static void ReceiveDataCallback(System.IAsyncResult ar)
474
+
475
+ {
476
+
477
+ //状態オブジェクトの取得
478
+
479
+ TcpRecvServer server = (TcpRecvServer)ar.AsyncState;
480
+
481
+
482
+
483
+ //読み込んだ長さを取得
484
+
485
+ int len = 0;
486
+
487
+ try
488
+
489
+ {
490
+
491
+ if(server.socket.Connected)len = server.socket.EndReceive(ar);
492
+
493
+ }
494
+
495
+ catch (System.ObjectDisposedException)
496
+
497
+ {
498
+
499
+ //閉じた時
500
+
501
+ System.Console.WriteLine("閉じました。");
502
+
503
+ server.OnDeleteFlg();
504
+
505
+ return;
506
+
507
+ }
508
+
509
+
510
+
511
+ //切断されたか調べる
512
+
513
+ if (len <= 0)
514
+
515
+ {
516
+
517
+ System.Console.WriteLine("切断されました。");
518
+
519
+ server.socket.Close();
520
+
521
+ server.OnDeleteFlg();
522
+
523
+ return;
524
+
525
+ }
526
+
527
+
528
+
529
+ //受信したデータを蓄積する
530
+
531
+ Array.Resize(ref server.ReceiveBuffer, len);
532
+
533
+ server.recvTempDataList.AddRange(server.ReceiveBuffer);
534
+
535
+
536
+
537
+ //受信用配列のサイズを元に戻す
538
+
539
+ Array.Resize(ref server.ReceiveBuffer, TcpRecvServer.BUFSIZE);
540
+
541
+
542
+
543
+ //データの整形
544
+
545
+ while (server.recvTempDataList.Count>sizeof(int))
546
+
547
+ {
548
+
549
+ int byteSize = (int)server.recvTempDataList[0];
550
+
551
+ if (server.recvTempDataList.Count > byteSize+sizeof(int))
552
+
553
+ {
554
+
555
+ byte[] addData;
556
+
557
+ addData = server.recvTempDataList.GetRange(sizeof(int), byteSize).ToArray();
558
+
559
+ server.AddRecvDateList(addData);
560
+
561
+ server.recvTempDataList.RemoveRange(0, sizeof(int) + byteSize);
562
+
563
+ }
564
+
565
+ else
566
+
567
+ {
568
+
569
+ break;
570
+
571
+ }
572
+
573
+ }
574
+
575
+
576
+
577
+ //再び受信開始
578
+
579
+ if(server.socket.Connected)server.socket.BeginReceive(server.ReceiveBuffer,
580
+
581
+ 0,
582
+
583
+ server.ReceiveBuffer.Length,
584
+
585
+ System.Net.Sockets.SocketFlags.None,
586
+
587
+ new System.AsyncCallback(ReceiveDataCallback),
588
+
589
+ server);
590
+
591
+ }
592
+
593
+
354
594
 
355
595
  }
356
596
 
357
597
 
358
598
 
599
+
600
+
601
+
602
+
359
603
  ```
360
604
 
361
605
  ### 実装環境