由于各种原因,需要在Windows下面实现一个关于UDP通信的模块,使用线程去处理数据接收和发送的功能。
main.cpp
extern "C" {
#include "udpMediaService.h"
}
#include <windows.h>
#include <string>
#include <vector>
#include <time.h>
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(filefind.name,".."))continue;
// if ((_A_SUBDIR==filefind.attrib))
// {
// //cout<<filefind.name<<"(dir)"<<endl;
// curr=String(path) + "\\";
// filesearch(curr);
// }
// else
// {
// //cout<<filefind.name<<endl;
// if (NULL != strstr(filefind.name, ".avi"))
// {
// memcpy(filename[count], filefind.name, strlen(filefind.name));
// //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", 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);
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
|
#ifndef UDPMEDIASERVICE_H
#define UDPMEDIASERVICE_H
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include <WS2tcpip.h>
#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下面编写的,就是发送一些数据过来。