1. 아키텍처 설명 현재 프로토콜은 다음과 같은 특징을 가지고 있습니다.
1) 클라이언트는 서버에 요청을 보내고 각 요청의 길이는 가변적입니다. 요청의 길이는 첫 번째 INT에 지정됩니다.
2) 각 서버는 일반적으로 여러 클라이언트에 서비스를 제공합니다. 예를 들어 TS는 CP와 NP에 동시에 서비스를 제공해야 합니다.
CP는 NP와 다른 CP에게 서비스를 제공하며, 다른 CP, TS, SP의 클라이언트이기도 하다.
3) 각 서버가 클라이언트에 서비스를 제공하는 경우 일반적으로 장기적이며 여러 요청-응답이 필요합니다.
이러한 구조는 주로 많은 수의 동시 클라이언트 연결을 지원하도록 설계되었습니다. 동시 클라이언트 연결 수가 많은 경우 스레드를 사용하든 프로세스를 사용하든 효과적인 서비스를 제공할 수 없으므로 select를 사용해야 합니다.
폴링 모드.
2. 기본 데이터 구조 설명: 각 클라이언트에 대해 현재 CPnew.c, SPnew.c에 해당하는 일부 정보를 저장해야 합니다.
Session으로 구성된 TSnew.c의 핵심 데이터 구조와 기본적으로 동일하며,
SessionCluster(TSnew.c) 또는 ServerDesc(CPnew.c 및 SPnew.c)로 구성됩니다.
그 중 Session은 각 클라이언트와 관련된 데이터이고, SessionCluster(또는 ServerDesc)는 서비스와 관련된 각 Session에 대한 포인터를 가지고 있는 각 서비스에 대한 정보이다.
이 데이터 구조는 클라이언트 요청이 있을 때 동적으로 할당되지 않고 초기 초기화 시 할당됩니다. 새로운 클라이언트 요청이 오면 서버는 이러한 사전 할당된 세션을 검색하고 일부 유휴 세션이 있음을 찾습니다. 유휴 시간이 없으면 오류를 보고합니다.
TS와 CP(SP)의 가장 큰 차이점은 TS가 UDP 프로토콜을 사용하는 반면, CP와 SP는 TCP 프로토콜을 사용한다는 것입니다.
1) TCP 프로토콜 클라이언트의 경우 각 클라이언트가 서로 다른 소켓을 사용하므로 선택 후 각 클라이언트의 fd_set이 설정되어 있는지 확인하면 됩니다. UDP 클라이언트의 경우 TS가 사용하는 해당 클라이언트를 찾으면 됩니다. 검색으로 인한 오버헤드를 줄이기 위한 몇 가지 조치.
2) TCP 프로토콜에서는 전송되는 데이터가 스트림 형태이므로 메시지를 블록으로 나누어야 하며 한 번의 읽기로 두 개의 메시지를 읽어야 할 수도 있고, 메시지를 여러 번 읽어야 할 수도 있습니다. 두 가지 상황을 모두 고려해야 합니다. 따라서 각 세션에는 읽었지만 아직 처리되지 않은 메시지를 저장하는 데 사용되는 buf, rstart 및 rlen이 있습니다.
마찬가지로 쓰기 과정에서 쓰기가 한 번에 완료되지 않을 수 있다는 점을 고려해야 하므로 각 세션마다 wbuf, wstart 및 wlen을 유지해야 합니다. 이는 프로토콜에서 다릅니다. 구현에서는 각 UDP 패킷에 포함된 메시지가 모두 완전한 것으로 가정하므로 이러한 항목은 포함되지 않습니다.
SessionCluster(또는 ServerDesc)는 여러 주요 부분으로 구성된 서비스를 설명합니다.
1) 양말: 사용된 소켓을 설명합니다.
2) cur : 현재 클라이언트 수
3) max: 수용할 수 있는 최대 클라이언트 수
4) head: 세션의 선두, head[0]은 첫 번째 세션, head[max-1]은 마지막 세션
5) init: 이 서비스의 각 Session에서 수행해야 하는 초기화 작업(함수 포인터)
6) 프로세스: 본 서비스의 메시지 처리 기능
7) 폐쇄: 이 서비스에 필요한 소멸자
3. 주요 구조 설명
process_child: 주요 기능, 이 기능은 주로 양말과 wsocks를 설정하는 데 사용됩니다. SP 및 CP의 경우 wsocks는 Session>0일 때만 설정됩니다.
선택하다;
각 ServerDesc(또는 SessionCluster)에 대해 process_type
SP와 CP에서는 PUSHLIST 작업을 지원하기 위해 각 사이클 이전에 processJob을 수행해야 합니다.
CP에서도 주기적으로 periodCheck를 수행하여 TS에서 만료된 연결을 삭제하고, periodLog를 주기적으로 수행하여 만료된 고객 연결을 삭제합니다.
프로세스 유형:
각 세션에 대해 읽을 수 있는지 확인하십시오. 읽을 수 있으면 완전한 메시지가 있는지 확인하십시오.
*(unsigned int *)(rbuf+rstart) <= rlen
완전한 메시지가 없을 때까지 해당 프로세스를 호출하여 쓰기 가능 여부를 확인하고 wlen>0이면 씁니다.
4. 기타 중요한 모듈
1) 구성 모듈 구성 모듈은 주로 struct NamVal, read_config, free_config로 구성됩니다.
Name은 cfg 파일의 이름이고, ptr은 저장소에 대한 포인터이며, type은 데이터 유형입니다. 현재 지원되는 유형은 다음과 같습니다.
d: 정수 유형, ptr은 정수 포인터입니다.
s: 문자열 유형, ptr은 포인터에 대한 포인터, (char **)
b: 문자열 버퍼 유형, ptr은 char *입니다. s 유형의 경우 이 유형을 사용할 때 주의해야 합니다.
read_config는 val에 메모리(malloc)를 할당하지만 b 유형의 경우 ptr은 할당된 메모리를 가리켜야 합니다.
두 가지 중요한 기능은 다음과 같습니다.
read_config, 매개변수는 파일 이름, 구조체 NamVal * 및 구조체 NamVal의 항목 수입니다.
free_config, 매개변수는 구조체 NamVal *과 동일하고 항목 수는 read_config와 같습니다.
2) MySQL 모듈
mysql 모듈은 주로 MYSQL *local_mysql과 세 가지 함수로 구성됩니다.
init_mysql, mysql 초기화, MYSQL * 반환, 일반적으로 local_mysql 초기화에 사용됨
query_mysql, mysql 문을 실행합니다. 형식은 query_mysql(local_mysql, "mysql 문,
%s에서 삭제 등 형식은 printf와 동일합니다." 필수값)
query_mysql_select는 mysql select 문을 실행합니다. 위와는 달리
MYSQL_RES *.
3) 네트워크 정렬 모듈은 주로 네트워크 구조, readNETBLOCK 함수, getnetwork 함수, CompareNet 함수로 구성됩니다.
readNETBLOCK은 네트워크 구성 파일을 읽고 전역 변수 NETBLOCKS를 초기화하는 데 사용됩니다.
MAX_NET 항목이 포함된 네트워크 구조의 배열입니다.
getnetowrk는 IP 주소에 가장 가까운 넷블록을 찾는 데 사용됩니다.
CompareNet은 동일한 네트워크에 있는 NPPeer가 1순위가 되도록 검색된 NPPeer를 정렬하기 위해 qsort에서 사용되는 기능입니다.
4) 그래프 관리 현재 CP, SP, NP에서는 CP가 동시에 여러 채널에 참여할 수 있고, NP도 여러 리소스를 가질 수 있습니다. 이러한 구조를 설명하기 위해 각 에지(Edge)라는 개념이 도입되었습니다. )는 NP에 대한 포인터, 채널에 대한 포인터,
TS에서는 이 세션의 각 간격을 이 채널에 저장해야 합니다. 각 채널은 Edge를 통과합니다.
cnext in은 연결된 목록에 연결되어 있습니다. 이 연결된 목록의 헤드는 채널 구조의 PeerHead이며 각 세션입니다.
Edge의 enext도 연결 목록에 연결되어 있으며 이 연결 목록의 헤드는 세션 구조의 헤더입니다.
관련 기능은 다음과 같습니다.
newEdge: 새 엣지를 추가합니다. 매개변수는 Channel *, Session *입니다. TS의 경우 Edge에서 정보를 초기화하려면 ChannelInfo가 필요합니다.
delEdge: 모서리를 삭제합니다. 매개변수는 Edge *입니다.
5) 채널 모듈
채널 모듈의 주요 기능은 다음과 같습니다.
TS는 NEED_PEERS를 처리하는 데 사용되고, SP도 채널 데이터를 저장하고 검색해야 하며, 채널은 그래프 구조를 사용하여 관리됩니다.
채널 검색은 효율성을 위해 해시를 사용합니다.
hash_str에 표시된 대로 해시입니다.
TS의 채널은 상대적으로 간단하며, SP와 CP의 채널도 채널 관련 데이터를 관리해야 합니다. 이러한 데이터는 파일 이름으로 하드 디스크의 /var/tmp/ 디렉터리에 저장됩니다. 각 관련 정보에 대해
BlockData에 의해 저장되는 Firstsampl, message_size, message_id 및 BlockData의 오프셋은 각각 파일에 첫 번째 샘플 정보, 블록 길이, 블록 ID 및 오프셋을 저장합니다.
SP와 CP의 처리는 서로 다릅니다. CP의 경우 블록은 해시 모드로 저장되지만 블록 ID는 1000입니다.
max_queue가 100이면 저장 위치는 1000%100=0입니다. SP의 경우 리소스가 CS에서 보낸 채널인 경우
순환 큐이며, 각 블록은 해당 위치에 순서대로 저장됩니다. 큐의 끝에 도달하면 큐의 선두부터 시작하며, 리소스가 파일인 경우에는 BlockData 정보가 저장되지 않습니다. 원본 파일은 blockID에 따라 직접 위치합니다.
Locate_by_id, Locate_order_by_id, newChannel 등 채널과 관련된 많은 함수가 있습니다.
freeChannel, saveBlock 등
6) Berkeley DB 모듈은 SP에만 관련되어 있으며 주로 DB 파일을 열고 특정 md5의 위치를 쿼리합니다.
openDB와 openMedia의 두 가지 기능
openDB: 매개변수는 DB 파일의 이름입니다.
openMedia: 매개변수는 md5 및 정수 포인터이며, FILE * 및 파일 길이를 정수 포인터로 반환합니다.
7) 직무모듈
Job 모듈은 CP와 SP에서 PUSHLIST를 처리하는 데 사용됩니다. PUSHLIST 메시지는 Job 목록을 재설정할 수 있습니다.
작업을 추가하거나 삭제할 수도 있습니다. JobDes 구조와 JobDes 구조의 세션 *은 작업이 속한 세션과 채널을 식별하는 데 사용됩니다. num은 다운로드해야 하는 BlockID의 수를 나타내며, 작업은 정수에 대한 포인터이고, 마스크도 정수에 대한 포인터입니다.
job[i]는 다운로드해야 하는 BlockID입니다. 마스크[i]가 0이면 다운로드해야 합니다.
addJob: Job 추가 시 해당 Job이 이미 목록에 있는지 확인하지 않고, 직접 Job을 생성하여 Linked List에 추가합니다.
deleteJob: 작업을 삭제할 때 작업 목록의 모든 작업에서 동일한 세션 및 채널을 사용하는 작업을 확인합니다.
그런 다음 삭제해야 하는 blockID의 해당 마스크를 1로 설정합니다.
processJob: cur부터 시작하는 각 작업에 대해 process_P2P_REQUEST_real을 사용하여 마스크 0이 있는 첫 번째 블록을 전송합니다. 모두 1이면 작업을 삭제합니다.
freeJob: JobDes를 삭제합니다.
freeJobList: 세션이 종료될 때 일반적으로 사용되는 세션의 모든 JobDes를 삭제합니다.
8) 간격 모듈
Interval 모듈은 TS에서 NP의 모든 빠른 간격을 나타내는 데 사용됩니다. 현재 블록 간격은 시작 필드와 길이 필드로 식별됩니다. Interval의 주요 작업은 병합 및 삭제입니다.
원래 간격과 새 간격 목록을 결합하는 반면 삭제는 원래 간격 목록에서 새 간격 목록을 제거합니다.
merge: 알고리즘은 버퍼 간격 목록 tmp를 사용하여 다음과 같습니다.
if (old[i] < new[j]) tmp[k] = old[i];
그렇지 않으면 tmp[k] = new[j];
그런 다음 tmp[k]로 병합할 수 있는 이전 항목과 새 항목을 살펴보세요.
삭제: 더 복잡합니다. 다음 상황을 고려하세요.
old[i]의 시작이 new[j]의 끝보다 큽니다.
old[i]의 끝은 new[j]의 시작 이전입니다.
old[i]와 new[j]에는 공통 부분이 있으며,
old[i]는 new[j]에 포함됩니다.
new[j]는 old[i]에 포함되어 서로 포함되지 않고, new[j]는 이전 것에 포함되어 서로 포함되지 않으며, old[i]는 이전에 포함됩니다.
5. 일부 빠른 알고리즘
1) UDP를 사용하는 TS에서는 클라이언트가 처음 로그인할 때 유휴 세션을 찾아야 합니다. 또한, 이 경우 클라이언트가 LOGIN 메시지를 반복적으로 보낼 수 있는지 확인해야 합니다. 셋째, 클라이언트가 메시지를 보낼 때 해당 세션을 찾아야 합니다.
이러한 쿼리를 피하기 위해 각각 다음과 같은 방법이 사용됩니다.
먼저 Hash 테이블을 생성합니다. 처음에는 모든 무료 세션이 Hash[0]에 연결됩니다. 새 클라이언트가 올 때마다 해당 세션은 Hash[0]에서 꺼내어 해당 해시 ID에 연결됩니다. 해시로 얻은 값은 0이 될 수 없습니다. 0이면 가능한 가장 큰 해시드가 반환됩니다.
소스 포트와 IP 주소를 기반으로 세션을 쿼리하는 경우에도 이 해시 테이블이 사용됩니다.
클라이언트는 메시지를 보낼 때 확인에 사용되는 7바이트 중 처음 3바이트를 사용하고, 이 3바이트를 세션을 식별하는 데 사용합니다.
아래 첨자를 사용하여 쿼리 오버헤드를 방지합니다.
2) 검색 횟수를 줄이려면 maxid를 사용하세요.
해시는 TCP에서 사용되지 않습니다. maxid 항목은 세션에서 가장 큰 ID를 기록하는 데 사용됩니다.
초기화 중에는 ID가 가장 작은 유휴 Session을 검색하므로 Session은 상대적으로 컴팩트하다고 볼 수 있습니다.
SP와 CP는 TS보다 훨씬 적은 수의 클라이언트를 지원하므로 이 처리가 허용됩니다.
고객이 종료하면 maxid를 업데이트해야 할 수도 있습니다. 이 업데이트는 Clientclosure에 의해 완료됩니다.
Clientclosure는 maxid를 업데이트한 다음 해당 소멸자를 호출합니다.
3) 장기간 유휴 상태인 연결의 타임아웃 처리 타임아웃 처리는 시스템 자원을 절약하기 위해 전체 목록을 순회해야 하므로,
또한 IDLE은 일반적으로 시스템 통계를 정기적으로 보고해야 하므로 적시성이 필요합니다.
일반적으로 periodLog 또는 periodCheck는 두 작업 중 수행할 작업을 결정합니다.
4) CPPeer 쿼리 시 현재는 GCP만 지원하는 점을 고려하여 GCPCHOICE를 직접 사용하고 현재 로드가 가장 작은 GCP로 설정하여 GCP 보고나 GCP 로그인 및 로그아웃 시 업데이트합니다.
6. 메시지 처리
1) TS 메시지 처리
NP2TS_LOGIN: NP는 TS에 로그인하고 소스 IP 주소와 보고된 npport에 따라 해시합니다. NP2TS_LOGIN 메시지가 마지막으로 전송된 이후의 시간이 SILENCE_TIME보다 작으면 직접 반환하고, 그렇지 않으면 WELCOME 메시지가 전송됩니다.
NP2TS_REPORT: 보고 간격 정보입니다. 새로 고침이 true이면 먼저 추가된 후 삭제됩니다.
NP2TS_NEED_PEERS: 피어 정보 쿼리, findCPPeer를 사용하여 적합한 CP 찾기, findNPPeers 사용
적합한 NP를 검색합니다. NP 검색 시 결과를 찾은 후 동일한 네트워크에 있는 항목이 1순위가 되도록 네트워크별로 정렬합니다.
NP2TS_LOGOUT: 종료
NP2TS_RES_LIST: 현재 NP의 모든 RESOURCE를 보내고 처리를 위해 addSession을 사용합니다. 이 에지가 아직 존재하지 않으면 추가합니다.
NP2TS_REQ_RES: RES를 추가하고 피어를 반환합니다.
NP2TS_DEL_RES: RES 삭제
CP2TS_REGISTER: 로그인, CP가 TS에 로그인, 소스 IP 주소에 따라 해시 및 보고된 npport,
CP2TS_REGISTER가 마지막으로 전송된 이후 ILENCE_TIME이면 직접 반환하고 그렇지 않으면 전송합니다.
환영 메시지.
CP2TS_UPDATE: CP 부하 보고
CP2TS_NEED_PEERS: ECP 쿼리에 사용됨, 아직 사용되지 않음
2) SP 메시지 처리
P2P_HELLO: 채널에 가입하세요.
채널이 존재하고 미디어 파일인 경우: 이 채널의 최소 및 최대 blockID를 나타내는 SPUPDATE를 반환합니다.
그렇지 않은 경우: 이 채널이 종료된 경우 종료 정보를 반환합니다. 채널이 존재하지 않고 미디어 파일인 경우: 이 채널의 최소 및 최대 blockID를 나타내는 SPUPDATE를 반환하고, 그렇지 않은 경우 SPUPDATE를 반환합니다. 오류를 나타냅니다.
P2P_PUSHLIST: 작업 목록을 재설정하거나 추가 또는 삭제합니다. 재설정 시 관련 작업을 모두 삭제한 후 추가 또는 삭제합니다.
CS2SP_REGISTER: 채널 생성
CS2SP_UPDATE: 채널 정보 업데이트
CS2SP_BLOCK: 데이터 블록 보내기
3) CP 메시지 처리
P2P_HELLO: 채널에 참여하고 제공된 SP 주소를 기반으로 해당 연결을 설정합니다.
P2P_PUSHLIST: 작업 목록 재설정 또는 추가 및 삭제
P2P_SPUPDATE: SP에서 보낸 SPUPDATE가 미디어 파일인 경우 NP로 전달되지 않습니다.
P2P_RESPONSE: SP가 보낸 데이터 블록입니다.
또한 CP도 TS에 등록해야 합니다.
현재 한 가지 유형의 GCP만 사용 중입니다.
확장하다