? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?每一天都值得去热爱!
udp客户端代码
#include
? ?int sockets=0; ? ?sockets=socket(AF_INET,SOCK_DGRAM,0); ? ?if(sockets<0){ ? ? ?printf("socket connect failed"); ?? ? return -1; ? ?} ? ?printf("socket initialize success\n"); ? ?while(1){ ? ? int tolen=0; ?? ?int ret=0; ?? ?char buf[1024]={0}; ?? ?gets(buf);
? ?struct sockaddr_in ? client; ? ?memset(&client, 0, sizeof(client)); ? ?client.sin_family = AF_INET; ? ?client.sin_port = htons(8888); ? ?client.sin_addr.s_addr = inet_addr("192.168.132.1"); ? ?ret=sendto(sockets,(char *)&buf, sizeof(buf),0,(struct sockaddr *) &client, sizeof(client)); ?? ?if(ret<0){ ?? ? ? printf("sendto failed"); ?? ? ? return -1; ?? ?} ? ?printf("sendto success\n");
? ?ret=recvfrom(sockets,(char *)&buf, sizeof(buf),0,(struct sockaddr *) &client,(socklen_t *)&client); ?? ?if(ret<0){ ?? ? ?printf("recvfrom failed"); ?? ? ?return -1; ?? ?} ?? ?printf("IP=%s,port=%d\n",inet_ntoa(client.sin_addr),ntohs(client.sin_port)); ?? ?printf("recvfrom success\n"); ?? ?printf("receive: ?%s\n",buf);
? ? closesocket(sockets); ? ? WSACleanup(); ?} }
?
服务器端代码
#include
? ?int sockets=0; ? ?sockets=socket(AF_INET,SOCK_DGRAM,0); ? ?if(sockets<0){ ? ? ?printf("socket connect failed"); ?? ? return -1; ? ?} ? ?printf("socket initialize success\n");
? ?int ret=0; ? ?struct sockaddr_in ? server; ? ?memset(&server, 0, sizeof(server)); ? ?server.sin_family = AF_INET; ? ?server.sin_port = htons(8888); ? ?server.sin_addr.s_addr = inet_addr("192.168.132.1"); ? ?ret=bind(sockets,(struct sockaddr *)&server,sizeof(server)); ? ?if(ret<0){ ? ? ? printf("bind failed"); ?? ? ?return -1; ? ?} ? ?printf("bind success\n");
? while(1){ ? ? int addrlen=0; ? ? char buf[1024]={0}; ?? ?struct sockaddr_in clientaddr={0}; ?? ?addrlen=sizeof(clientaddr); ?? ?ret=recvfrom(sockets,(char *)&buf, sizeof(buf),0,(struct sockaddr *) &clientaddr,(socklen_t *)&addrlen); ?? ?if(ret<0){ ?? ? ?printf("recvfrom failed"); ?? ? ?return -1; ?? ?} ?? ?printf("IP=%s,port=%d\n",inet_ntoa(clientaddr.sin_addr),ntohs(clientaddr.sin_port)); ?? ?printf("recvfrom success\n"); ?? ?printf("receive: ?%s\n",buf);
?? ?memset(buf,0,sizeof(buf)); ?? ?gets(buf); ?? ?ret=sendto(sockets,(char *)&buf, sizeof(buf),0,(struct sockaddr *) &server, sizeof(server)); ?? ?if(ret<0){ ?? ? ? printf("sendto failed"); ?? ? ? return -1; ?? ?} ?? ?printf("sendto success\n"); ?? ? ? ?closesocket(sockets); ? ?WSACleanup(); ? ?} }
运行效果:
?
?
? ? 由于各种原因,需要在Windows下面实现一个关于UDP通信的模块,使用线程去处理数据接收和发送的功能。
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
extern
"C"
{
#include "udpMediaService.h"
}
#include
#include
#include
#include
using
namespace
std
;
bool
FindOrCreateDirectory
(
const
char
*
pszPath
)
{
WIN32_FIND_DATA
fd
;
HANDLE
hFind
=
::
FindFirstFile
(
pszPath
,
&
fd
);
while
(
hFind
!=
INVALID_HANDLE_VALUE
)
{
if
(
fd
.
dwFileAttributes
&
FILE_ATTRIBUTE_DIRECTORY
)
return
true
;
}
if
(
!::
CreateDirectory
(
pszPath
,
NULL
)
)
{
//char szDir[MAX_PATH];
//sprintf_s( szDir, sizeof(szDir), "创建目录[%s]失败,请检查权限", pszPath );
//Output("the error is %s", szDir);
//return false;
}
return
true
;
}
// 遍历目录
bool
CheckDirectory
(
char
*
pszPath
)
{
vector
<
std
::
string
>
vtPath
;
const
char
*
sep
=
"
\\
/"
;
char
*
next_token
;
char
*
token
=
strtok_s
(
pszPath
,
sep
,
&
next_token
);
while
(
token
!=
NULL
)
{
vtPath
.
push_back
(
token
);
token
=
strtok_s
(
NULL
,
sep
,
&
next_token
);
}
if
(
vtPath
.
size
()
>
0
)
{
if
(
vtPath
[
0
]
==
"."
)
vtPath
.
erase
(
vtPath
.
begin
()
);
}
// 核查所有路径是否存在
std
::
string
strCurPath
;
for
(
size_t
i
=
0
;
i
<
(
int
)
vtPath
.
size
();
++
i
)
{
strCurPath
+=
vtPath
[
i
];
strCurPath
+=
'\\'
;
if
(
!
FindOrCreateDirectory
(
strCurPath
.
c_str
()
)
)
{
return
false
;
}
}
return
true
;
}
DWORD
WINAPI
mediaRecvPthread
(
LPVOID
pM
)
{
char
buffer
[
BUFFER_SIZE
]
=
{
0
};
int
mediaRecvLen
=
-
1
;
int
mediaRecvStatus
=
1
;
char
mediaPath
[
128
]
=
{
0
};
int
err
;
BOOL
bDontLinger
=
FALSE
;
BOOL
bReuseaddr
=
TRUE
;
int
nNetTimeout
=
TIME
;
//阻塞
int
recvAddrLen
=
0
;
char
localip
[
20
];
char
filePath
[
128
]
=
{
0
};
MEDIAPATH
*
mediaValue
=
(
MEDIAPATH
*
)
pM
;
int
port
=
atoi
(
mediaValue
->
mediaValue
);
memcpy
(
filePath
,
mediaValue
->
filePath
,
sizeof
(
mediaValue
->
filePath
));
//unsigned long ul = 1;
SOCKET
mediaRecvSock
;
struct
sockaddr_in
mediaRecvAddr
;
struct
sockaddr_in
mediaRecvFromAddr
;
WSADATA
wsaData
;
WSAStartup
(
MAKEWORD
(
2
,
2
),
&
wsaData
);
printf
(
"port is %d.
\n
"
,
port
);
printf
(
"filePath is %s.
\n
"
,
filePath
);
mediaRecvSock
=
socket
(
AF_INET
,
SOCK_DGRAM
,
IPPROTO_UDP
);
//if (SOCKET_ERROR == ioctlsocket(recvSocket, FIONBIO, (unsigned long *)&ul)) //设置成非阻塞函数
//{
// printf("ioctlsocket fiald\n");
// return -1;
//}
memset
(
&
mediaRecvAddr
,
0
,
sizeof
(
recvAddr
));
mediaRecvAddr
.
sin_family
=
AF_INET
;
mediaRecvAddr
.
sin_addr
.
S_un
.
S_addr
=
htonl
(
INADDR_ANY
);
//mediaRecvAddr.sin_addr.S_un.S_addr = inet_addr(SERVERIP);
mediaRecvAddr
.
sin_port
=
htons
(
port
);
recvAddrLen
=
sizeof
(
mediaRecvAddr
);
if
(
0
!=
bind
(
mediaRecvSock
,
(
SOCKADDR
*
)
&
mediaRecvAddr
,
recvAddrLen
))
{
printf
(
"mediaRecvInit Bind filed!
\n
"
);
return
-
1
;
}
setsockopt
(
mediaRecvSock
,
SOL_SOCKET
,
SO_DONTLINGER
,
(
const
char
*
)
&
bDontLinger
,
sizeof
(
BOOL
));
setsockopt
(
mediaRecvSock
,
SOL_SOCKET
,
SO_REUSEADDR
,
(
const
char
*
)
&
bReuseaddr
,
sizeof
(
BOOL
));
setsockopt
(
mediaRecvSock
,
SOL_SOCKET
,
SO_RCVTIMEO
,
(
const
char
*
)
&
nNetTimeout
,
sizeof
(
BOOL
));
FILE
*
mediaFp
=
fopen
(
filePath
,
"wb"
);
while
(
mediaRecvStatus
)
{
mediaRecvLen
=
recvfrom
(
mediaRecvSock
,
buffer
,
sizeof
(
buffer
),
0
,
(
SOCKADDR
*
)
&
mediaRecvFromAddr
,
&
recvAddrLen
);
if
(
mediaRecvLen
=
SOCKET_ERROR
)
{
err
=
WSAGetLastError
();
if
(
err
==
WSAEWOULDBLOCK
)
{
continue
;
}
else
if
(
err
==
WSAETIMEDOUT
)
//超时
{
printf
(
"recv timeout
\n
"
);
break
;
}
else
if
(
err
==
WSAENETDOWN
)
//连接断开
{
printf
(
"recv connection break
\n
"
);
break
;
}
else
//其他错误
printf
(
"other error
\n
"
);
break
;
}
else
{
fwrite
(
buffer
,
sizeof
(
char
),
mediaRecvLen
,
mediaFp
);
}
}
fclose
(
mediaFp
);
closesocket
(
mediaRecvSock
);
WSACleanup
();
return
0
;
}
//XXX:使用带头结点的单向链表 存放用户信息
int
memoryError
(
USERINFO
*
p
)
//判断内存是否申请成功
{
if
(
p
==
NULL
)
{
printf
(
"MEMORY ERROR!"
);
return
1
;
}
return
0
;
}
int
creatUserList
(
USERINFO
*
head
)
{
if
(
memoryError
(
head
))
return
-
1
;
head
->
next
=
NULL
;
}
int
addUser
(
USERINFO
*
head
,
MEDIAINFO
data
)
//始终在表头插入
{
USERINFO
*
new_create
=
(
USERINFO
*
)
malloc
(
sizeof
(
USERINFO
));
if
(
memoryError
(
new_create
))
return
-
1
;
new_create
->
mediaInfo
=
data
;
new_create
->
next
=
head
->
next
;
head
->
next
=
new_create
;
}
int
delUser
(
USERINFO
*
head
,
char
name
[
10
])
{
USERINFO
*
q
=
head
;
USERINFO
*
p
=
head
->
next
;
while
(
p
!=
NULL
)
{
if
(
strcmp
((
p
->
mediaInfo
).
uid
,
name
)
==
0
)
break
;
q
=
p
;
p
=
p
->
next
;
}
if
(
p
==
NULL
)
{
printf
(
"删除用户失败
\n
"
);
return
-
1
;
}
q
->
next
=
p
->
next
;
free
(
p
);
p
=
NULL
;
}
int
findUser
(
USERINFO
*
head
,
char
name
[
10
])
{
USERINFO
*
p
=
head
->
next
;
while
(
p
!=
NULL
)
{
if
(
strcmp
((
p
->
mediaInfo
).
uid
,
name
)
==
0
)
return
0
;
p
=
p
->
next
;
}
if
(
p
==
NULL
)
return
-
1
;
}
int
getMediaPort
()
{
SOCKET
s
;
int
port
;
struct
sockaddr_in
addr
;
s
=
socket
(
AF_INET
,
SOCK_DGRAM
,
IPPROTO_UDP
);
memset
(
&
addr
,
0
,
sizeof
(
addr
));
addr
.
sin_family
=
AF_INET
;
addr
.
sin_addr
.
S_un
.
S_addr
=
htonl
(
INADDR_ANY
);
for
(
port
=
5500
;
port
<
65535
;
port
++
)
{
addr
.
sin_port
=
htons
(
port
);
if
(
0
==
bind
(
s
,
(
struct
sockaddr
*
)
&
addr
,
sizeof
(
addr
)))
{
break
;
}
}
closesocket
(
s
);
return
port
!=
65535
?
port
:
-
1
;
}
int
getNowTime
(
char
*
nowTime
)
{
char
acYear
[
5
]
=
{
0
};
char
acMonth
[
5
]
=
{
0
};
char
acDay
[
5
]
=
{
0
};
char
acHour
[
5
]
=
{
0
};
char
acMin
[
5
]
=
{
0
};
char
acSec
[
5
]
=
{
0
};
time_t
now
;
struct
tm
*
timenow
;
time
(
&
now
);
timenow
=
localtime
(
&
now
);
strftime
(
acYear
,
sizeof
(
acYear
),
"%Y"
,
timenow
);
strftime
(
acMonth
,
sizeof
(
acMonth
),
"%m"
,
timenow
);
strftime
(
acDay
,
sizeof
(
acDay
),
"%d"
,
timenow
);
strftime
(
acHour
,
sizeof
(
acHour
),
"%H"
,
timenow
);
strftime
(
acMin
,
sizeof
(
acMin
),
"%M"
,
timenow
);
strftime
(
acSec
,
sizeof
(
acSec
),
"%S"
,
timenow
);
strncat
(
nowTime
,
acYear
,
4
);
strncat
(
nowTime
,
acMonth
,
2
);
strncat
(
nowTime
,
acDay
,
2
);
strncat
(
nowTime
,
acHour
,
2
);
strncat
(
nowTime
,
acMin
,
2
);
strncat
(
nowTime
,
acSec
,
2
);
return
0
;
}
int
changeStr
(
const
char
*
str1
,
const
char
*
str2
,
const
char
*
str3
,
const
char
*
str4
,
char
*
outstr
)
{
strncat
(
outstr
,
str1
,
strlen
(
str1
));
strncat
(
outstr
,
"//"
,
2
);
strncat
(
outstr
,
str2
,
strlen
(
str2
));
strncat
(
outstr
,
str3
,
strlen
(
str3
));
strncat
(
outstr
,
str4
,
strlen
(
str4
));
return
0
;
}
//DWORD WINAPI ThreadFun(LPVOID pM)
//{
// printf("子线程ID号为:%d\n", GetCurrentThreadId());
// return 0;
//}
int
mediaRecvPthreadInit
(
MEDIAPATH
*
mediaValue
)
{
HANDLE
mediaRecvHandle
=
NULL
;
mediaRecvHandle
=
CreateThread
(
NULL
,
0
,
mediaRecvPthread
,
mediaValue
,
0
,
NULL
);
if
(
NULL
==
mediaRecvHandle
)
{
printf
(
"Create Thread mediaRecvPthread error
\n
"
);
return
-
1
;
}
else
{
printf
(
"Create Thread mediaRecvPthread successfully
\n
"
);
//WaitForSingleObject(mediaRecvHandle, INFINITE);
WaitForSingleObject
(
mediaRecvHandle
,
50
);
}
return
0
;
//WaitForMultipleObjects(THREAD_NUM, (const HANDLE *)mediaRecvHandle, TRUE, INFINITE);
}
//static void filesearch(char const* path)
//{
// struct _finddata_t filefind;
// String curr = String(path) + "\\*.*";
// char tmp[128] = {0};
// char video_path[64] = {0};
// int done = 0, i, handle, j = 0, ret = -1, count = 0;
// char filename[50][32] = {0};
// if((handle=_findfirst(curr.c_str(),&filefind))==-1)return;
// while(!(done=_findnext(handle,&filefind)))
// {
// if(!strcmp(www.sychzs.cn,".."))continue;
// if ((_A_SUBDIR==filefind.attrib))
// {
// //cout< // curr=String(path) + "\\"; // filesearch(curr); // } // else // { // //cout< // if (NULL != strstr(www.sychzs.cn, ".avi")) // { // memcpy(filename[count], www.sychzs.cn, strlen(www.sychzs.cn)); // //Output("%d:%s\n", count, filename[count]); // count++; // } // } // } // if (count > file_count) // { // for (i = 0; i < count - file_count ; i++) // { // //Output("%d:%s\n", i, filename[i]); // curr=String(path) + "//" + filename[i]; // ret = remove(curr.c_str()); // memcpy(tmp, curr.c_str(), curr.length()); // memcpy(video_path, tmp + 56, 36); // //strncat(video_path, ".mp4", 4); // //Output("11111111111111the video_path is %s", video_path); // //del((const char *)video_path); // } // } // // _findclose(handle); //} int changePath ( char * uid , char * path ) { char comNum [ 2 ] = { 0 }; char banNum [ 4 ] = { 0 }; char houNum [ 4 ] = { 0 }; memcpy ( comNum , uid , 2 ); memcpy ( banNum , uid + 2 , 4 ); memcpy ( houNum , uid + 6 , 4 ); strcat ( path , "./apache-tomcat-7.0.37//webapps//FamilyGuardian//video//" ); strncat ( path , comNum , 2 ); strcat ( path , "//" ); strncat ( path , banNum , 4 ); strcat ( path , "//" ); strncat ( path , houNum , 4 ); return 0 ; } int createMediaPath ( char * uid , char * path ) { char tmpPath [ 128 ] = { 0 }; changePath ( uid , path ); memcpy ( tmpPath , path , sizeof ( tmpPath )); CheckDirectory ( tmpPath ); return 0 ; } int mediaServiceStart ( MEDIAINFO * mediaInfo , char * filePath ) { int mediaRecvPort = 0 ; MEDIAPATH mediaPath = { 0 }; char nowTime [ 32 ] = { 0 }; char path [ 128 ] = { 0 }; getNowTime ( nowTime ); //strncat(filePath, nowTime, strlen(nowTime)); //memcpy(mediaPath.filePath, filePath, strlen(filePath) + 1); if ( ! strncmp ( mediaInfo -> audio , "audio" , 5 )) { mediaRecvPort = getMediaPort (); memset ( mediaInfo -> audio , 0 , sizeof ( mediaInfo -> audio )); itoa ( mediaRecvPort , mediaInfo -> audio , 10 ); memcpy ( mediaPath . mediaValue , mediaInfo -> audio , sizeof ( mediaInfo -> audio )); memset ( path , 0 , sizeof ( path )); changeStr ( filePath , "00" , nowTime , ".wav" , path ); memcpy ( mediaPath . filePath , path , strlen ( path ) + 1 ); mediaRecvPthreadInit ( & mediaPath ); printf ( "mediaRecvPort is %d, mediaInfo->audio is %s. \n " , mediaRecvPort , mediaInfo -> audio ); } if ( ! strncmp ( mediaInfo -> video0 , "video0" , 6 )) { mediaRecvPort = getMediaPort (); memset ( mediaInfo -> video0 , 0 , sizeof ( mediaInfo -> video0 )); itoa ( mediaRecvPort , mediaInfo -> video0 , 10 ); memcpy ( mediaPath . mediaValue , mediaInfo -> video0 , sizeof ( mediaInfo -> video0 )); memset ( path , 0 , sizeof ( path )); changeStr ( filePath , "00" , nowTime , ".dat" , path ); memcpy ( mediaPath . filePath , path , strlen ( path ) + 1 ); mediaRecvPthreadInit ( & mediaPath ); printf ( "mediaRecvPort is %d, mediaInfo->video0 is %s. \n " , mediaRecvPort , mediaInfo -> video0 ); } if ( ! strncmp ( mediaInfo -> video1 , "video1" , 6 )) { mediaRecvPort = getMediaPort (); memset ( mediaInfo -> video1 , 0 , sizeof ( mediaInfo -> video1 )); itoa ( mediaRecvPort , mediaInfo -> video1 , 10 ); memcpy ( mediaPath . mediaValue , mediaInfo -> video1 , sizeof ( mediaInfo -> video1 )); memset ( path , 0 , sizeof ( path )); changeStr ( filePath , "01" , nowTime , ".dat" , path ); memcpy ( mediaPath . filePath , path , strlen ( path ) + 1 ); mediaRecvPthreadInit ( & mediaPath ); printf ( "mediaRecvPort is %d, mediaInfo->video1 is %s. \n " , mediaRecvPort , mediaInfo -> video1 ); } if ( ! strncmp ( mediaInfo -> video2 , "video2" , 6 )) { mediaRecvPort = getMediaPort (); memset ( mediaInfo -> video2 , 0 , sizeof ( mediaInfo -> video1 )); itoa ( mediaRecvPort , mediaInfo -> video2 , 10 ); memcpy ( mediaPath . mediaValue , mediaInfo -> video2 , sizeof ( mediaInfo -> video2 )); memset ( path , 0 , sizeof ( path )); changeStr ( filePath , "02" , nowTime , ".dat" , path ); memcpy ( mediaPath . filePath , path , strlen ( path ) + 1 ); mediaRecvPthreadInit ( & mediaPath ); printf ( "mediaRecvPort is %d, mediaInfo->video2 is %s. \n " , mediaRecvPort , mediaInfo -> video2 ); } if ( ! strncmp ( mediaInfo -> video3 , "video3" , 6 )) { mediaRecvPort = getMediaPort (); memset ( mediaInfo -> video3 , 0 , sizeof ( mediaInfo -> video3 )); itoa ( mediaRecvPort , mediaInfo -> video3 , 10 ); memcpy ( mediaPath . mediaValue , mediaInfo -> video3 , sizeof ( mediaInfo -> video3 )); memset ( path , 0 , sizeof ( path )); changeStr ( filePath , "03" , nowTime , ".dat" , path ); memcpy ( mediaPath . filePath , path , strlen ( path ) + 1 ); mediaRecvPthreadInit ( & mediaPath ); printf ( "mediaRecvPort is %d, mediaInfo->video3 is %s. \n " , mediaRecvPort , mediaInfo -> video3 ); } printf ( "uid is %s. \n " , mediaInfo -> uid ); printf ( "audio is %s. \n " , mediaInfo -> audio ); printf ( "video0 is %s. \n " , mediaInfo -> video0 ); printf ( "video1 is %s. \n " , mediaInfo -> video1 ); printf ( "video2 is %s. \n " , mediaInfo -> video2 ); printf ( "video3 is %s. \n " , mediaInfo -> video3 ); return 0 ; } DWORD WINAPI mediaServicePthread ( LPVOID pM ) { BOOL bDontLinger = FALSE ; BOOL bReuseaddr = TRUE ; //int nNetTimeout = TIME; //阻塞 int recvAddrLen = 0 ; char localip [ 20 ]; int recvLength = - 1 ; int sendLength = - 1 ; int recvAddrSize = sizeof ( recvFromAddr ); char recvBuffer [ BUFFER_SIZE ] = { 0 }; char filePath [ 128 ] = { 0 }; MEDIAINFO mediaInfo = { 0 }; //USERINFO *userInfoHead = NULL; //unsigned long ul = 1; WSADATA wsaData ; WSAStartup ( MAKEWORD ( 2 , 2 ), & wsaData ); recvSocket = socket ( AF_INET , SOCK_DGRAM , IPPROTO_UDP ); //if (SOCKET_ERROR == ioctlsocket(recvSocket, FIONBIO, (unsigned long *)&ul)) //设置成非阻塞函数 //{ // printf("ioctlsocket fiald\n"); // return -1; //} memset ( & recvAddr , 0 , sizeof ( recvAddr )); recvAddr . sin_family = AF_INET ; //recvAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); recvAddr . sin_addr . S_un . S_addr = inet_addr ( SERVERIP ); recvAddr . sin_port = htons ( SERVERPORT ); recvAddrLen = sizeof ( recvAddr ); if ( 0 != bind ( recvSocket , ( SOCKADDR * ) & recvAddr , recvAddrLen )) { printf ( "mediaRecvInit Bind filed! \n " ); return - 1 ; } setsockopt ( recvSocket , SOL_SOCKET , SO_DONTLINGER , ( const char * ) & bDontLinger , sizeof ( BOOL )); setsockopt ( recvSocket , SOL_SOCKET , SO_REUSEADDR , ( const char * ) & bReuseaddr , sizeof ( BOOL )); //setsockopt(recvSocket, SOL_SOCKET, SO_RCVTIMEO, (const char*)&nNetTimeout, sizeof(BOOL)); mediaServiceStatus = 1 ; while ( mediaServiceStatus ) { memset ( recvBuffer , 0 , sizeof ( recvBuffer )); recvLength = recvfrom ( recvSocket , recvBuffer , sizeof ( recvBuffer ), 0 , ( SOCKADDR * ) & recvFromAddr , & recvAddrSize ); recvBuffer [ recvLength ] = '\0' ; if ( strncmp ( "Media" , recvBuffer , 5 )) { continue ; } memcpy (( unsigned char * ) & mediaInfo , recvBuffer , recvLength ); mediaInfo . address = recvFromAddr ; //printf("uid is %s.\n", mediaInfo.uid); //printf("audio is %s.\n", www.sychzs.cn); //printf("video0 is %s.\n", www.sychzs.cn0); //printf("video1 is %s.\n", www.sychzs.cn1); //printf("video2 is %s.\n", www.sychzs.cn2); //printf("video3 is %s.\n", www.sychzs.cn3); if ( 0 != createMediaPath ( mediaInfo . uid , filePath )) { printf ( "create media path error \n " ); } if ( 0 != mediaServiceStart ( & mediaInfo , filePath )) { printf ( "media service start error \n " ); } memcpy ( recvBuffer , ( unsigned char * ) & mediaInfo , sizeof ( mediaInfo )); sendLength = sendto ( recvSocket , recvBuffer , sizeof ( mediaInfo ), 0 , ( SOCKADDR * ) & recvFromAddr , recvAddrSize ); if ( 0 > sendLength ) { printf ( "send mediaInfo error \n " ); } } closesocket ( recvSocket ); WSACleanup (); return 0 ; } int mediaServicePthreadInit () { HANDLE mediaServiceHandle = NULL ; mediaServiceHandle = CreateThread ( NULL , NULL , mediaServicePthread , NULL , 0 , NULL ); if ( NULL == mediaServiceHandle ) { printf ( "CreatePthread mediaServicePthread error. \n " ); return - 1 ; } else { printf ( "CreatePthread mediaServicePthread successfully. \n " ); } return 0 ; } int tempFun () { int ret = - 1 ; //ret = mediaRecvPthreadInit(); ret = mediaServicePthreadInit (); if ( - 1 == ret ) { printf ( "mediaRecvPthreadInit faild \n " ); return - 1 ; } else { printf ( "mediaRecvPthreadInit successfully \n " ); } return 0 ; } int main ( int argc , char * argv []) { char cmd [ 10 ] = { 0 }; tempFun (); //Sleep(10000); while ( 1 ) { printf ( "input 'quit' closed. \n " ); scanf ( "%s" , cmd ); if ( ! strncmp ( cmd , "quit" , 4 )) { break ; } } system ( "pause" ); return 0 ; } udpMediaService.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 #ifndef UDPMEDIASERVICE_H #define UDPMEDIASERVICE_H #include #include #include #include #pragma comment(lib, "ws2_32.lib") #define SERVERIP "192.168.1.77" #define SERVERPORT 7777 #define TIME 60*1000 #define BUFFER_SIZE 1500 #define THREAD_NUM 10 int mediaServiceStatus ; //int mediaRecvStatus = 0; typedef struct media_info { char media [ 6 ]; char uid [ 11 ]; char audio [ 6 ]; char video0 [ 7 ]; char video1 [ 7 ]; char video2 [ 7 ]; char video3 [ 7 ]; struct sockaddr_in address ; } MEDIAINFO ; typedef struct userList { MEDIAINFO mediaInfo ; struct userList * next ; } USERINFO ; typedef struct mediaValueFilePath { char mediaValue [ 7 ]; char filePath [ 128 ]; } MEDIAPATH ; SOCKET recvSocket ; struct sockaddr_in recvAddr ; struct sockaddr_in recvFromAddr , sendToRcevAddr ; SOCKET sendSocket ; struct sockaddr_in sendAddr ; struct sockaddr_in sendToAddr ; int mediaRecvInit (); int mediaSendInit (); int mediaRecv ( char * buffer , int len ); int mediaSend ( char * buffer , int len ); int mediaRecvEixt ( void ); int mediaSendExit ( void ); int memoryError ( USERINFO * p ); int creatUserList ( USERINFO * head ); int findUser ( USERINFO * head , char name [ 10 ]); int delUser ( USERINFO * head , char name [ 10 ]); int getAllUser ( USERINFO const * head ); int addUser ( USERINFO * head , MEDIAINFO data ); int getMediaPort (); int getNowTime ( char * nowTime ); int changeStr ( const char * str1 , const char * str2 , const char * str3 , const char * str4 , char * outstr ); int mediaRecvPthreadInit ( MEDIAPATH * mediaValue ); DWORD WINAPI mediaRecvPthread ( LPVOID pM ); //bool FindOrCreateDirectory( const char* pszPath ); //bool CheckDirectory( char* pszPath ); int createMediaPath ( char * uid , char * path ); int mediaServiceStart ( MEDIAINFO * mediaInfo , char * filePath ); DWORD WINAPI mediaServicePthread ( LPVOID pM ); int mediaServicePthreadInit (); #endif 测试代码是Linux下面编写的,就是发送一些数据过来。 “TCP是一种流模式的协议,UDP是一种数据报模式的协议”,这句话相信大家对这句话已经耳熟能详~但是,“流模式”与“数据包模式”在编程的时候有什么区别呢?以下是我的理解,仅供参考! 1、TCP 打个比方比喻TCP,你家里有个蓄水池,你可以里面倒水,蓄水池上有个龙头,你可以通过龙头将水池里的水放出来,然后用各种各样的容器装(杯子、矿泉水瓶、锅碗瓢盆)接水。 上面的例子中,往水池里倒几次水和接几次水是没有必然联系的,也就是说你可以只倒一次水,然后分10次接完。另外,水池里的水接多少就会少多少;往里面倒多少水,就会增加多少水,但是不能超过水池的容量,多出的水会溢出。 结合TCP的概念,水池就好比接收缓存,倒水就相当于发送数据,接水就相当于读取数据。好比你通过TCP连接给另一端发送数据,你只调用了一次 write,发送了100个字节,但是对方可以分10次收完,每次10个字节;你也可以调用10次write,每次10个字节,但是对方可以一次就收完。(假设数据都能到达)但是,你发送的数据量不能大于对方的接收缓存(流量控制),如果你硬是要发送过量数据,则对方的缓存满了就会把多出的数据丢弃。 2、UDP UDP和TCP不同,发送端调用了几次write,接收端必须用相同次数的read读完。UPD是基于报文的,在接收的时候,每次最多只能读取一个报文,报文和报文是不会合并的,如果缓冲区小于报文长度,则多出的部分会被丢弃。也就说,如果不指定MSG_PEEK标志,每次读取操作将消耗一个报文。 3、为什么 其实,这种不同是由TCP和UDP的特性决定的。TCP是面向连接的,也就是说,在连接持续的过程中,socket中收到的数据都是由同一台主机发出的(劫持什么的不考虑),因此,知道保证数据是有序的到达就行了,至于每次读取多少数据自己看着办。 而UDP是无连接的协议,也就是说,只要知道接收端的IP和端口,且网络是可达的,任何主机都可以向接收端发送数据。这时候,如果一次能读取超过一个报文的数据,则会乱套。比如,主机A向发送了报文P1,主机B发送了报文P2,如果能够读取超过一个报文的数据,那么就会将P1和P2的数据合并在了一起,这样的数据是没有意义的。 两个协议其他区别 TCP(Transmission Control Protocol)传输控制协议: 该协议主要用于在主机间建立一个虚拟连接,以实现高可靠性的数据包交换。IP协议可以进行IP数据包的分割和组装,但是通过IP协议并不能清楚地了解到数据包是否顺利地发送给目标计算机。而使用TCP协议就不同了,在该协议传输模式中在将数据包成功发送给目标计算机后,TCP会要求发送一个确认;如果在某个时限内没有收到确认,那么TCP将重新发送数据包。另外,在传输的过程中,如果接收到无序、丢失以及被破坏的数据包,TCP还可以负责恢复。 传输控制协议是一种面向连接的、可靠的、基于字节流的运输层通信协议,通常由IETF的RFC793说明。在简化的计算机网络OSI模型中,它完成运输层所指定的功能。 UDP (User Datagram Protocol) 用户数据报协议: 用户数据报协议(UDP)是 ISO参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。 UDP 协议基本上是 IP 协议与上层协议的接口。 UDP协议适用端口分辨运行在同一台设备上的多个应用程序。 由于大多数网络应用程序都在同一台机器上运行,计算机上必须能够确保目的地机器上的软件程序能从源地址机器处获得数据包,以及源计算机能收到正确的回复。这是通过使用UDP 的“端口号”完成的。 区别: 1、基于连接与无连接 TCP---传输控制协议提供的是面向连接、可靠的字节流服务。当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据。TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。 每个数据包的传输过程是:先建立链路、数据传输、然后清除链路。数据包不包含目的地址。受端和发端不但顺序一致,而且内容相同。它的可靠性高。 UDP---用户数据报协议是面向无连接的,每个数据包都有完整的源、目的地址及分组编号,各自在网络中独立传输,传输中不管其顺序,数据到达收端后再进行排序组装,遇有丢失、差错和失序等情况,通过请求重发来解决。它的效率比较高。 是一个简单的面向数据报的运输层协议。UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快。 2、对系统资源的要求(TCP较多,UDP少) 3、UDP程序结构较简单 4、流模式与数据报模式 5、TCP保证数据正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证 6、TCP是面可靠的字节流服务 ,UDP 并不提供对 IP协议的可靠机制、流控制以及错误恢复功能等。 ?