飛秋是由一個叫feiq18 的網站發布的,網站屬於陶先生所有,也就是說,陶先生是主要的負責人。因為飛秋主要面對對的是區域網路的信息傳輸,對於中小企業來說是主要目標,應該做成可定製版的,可以加企業的標識和信息等內容,包括圖示。這樣更容易讓企業認同,便於推廣。同時,可以針對企業的要求進行功能定製,這樣更有針對性。企業也不會因為一些企業不許可的功能而封殺。
基本介紹
- 中文名:飛秋工作室
- 對象:學生
- 平台: feiq18
- 作者:陶先生
軟體介紹,發展,原理,
軟體介紹
一款針對企業內部區域網路的多功能時事通訊軟體,叫做飛秋.
其實,這也就是軟體的模組化,方便開發和維護,同時,對用戶的需求和可以靈活的滿足。針對飛秋的話應該就是,外掛程式化,將成體功能拆分成若干外掛程式,這樣就可以在功能和體積上取得平衡點。也減輕了開發者的工作量和開發難度。
發展
該工作室從最初的飛鴿傳書軟體發展成飛秋軟體,經過數年時間就把軟體做的非常具有影響力,單位嚴禁上網,同事們工作之餘的娛樂就變得很單調,大多都是用來玩一些單機版的小遊戲,或者看影視劇,都是從家中下載了拷貝過來,在區域網路內的即時通訊工具“飛秋”上飛來飛去的相互傳閱。
作為區域網路聊天軟體 FreeEIM 跟飛秋是不一樣的,他完全由自己開發,飛秋工作室做開發的飛秋,是參考飛鴿傳書的傳書協定,他與飛鴿傳書是可以共同使用的,具有兼容性,而FreeEIM使用的是自主開發的協定,所以不能與飛鴿傳書一起使用,兩者可以並存,互不干擾。關於飛秋的跨網段通信的問題,昨天試了下如果兩台計算機都在路由器後面的話,就是說這兩台電腦都是通過路由器上公網,而每個路由器下面又有好多台計算機,我從“加其他網段好友”這個功能里加了相應的路由器的IP就可以加這個下面的線上好友了,它怎么能加為好友,又怎么能知道信息該發給誰呢,這是怎么實現的呢,哪位大哥能給解釋下它的原理呢,非常感謝?
原理
區域網路的資源豐富,使用Windows共享機制可以很方便的訪問大家的已分享檔案。但你能搜尋到和你不同網段的資源么。不行。那么使用其他的軟體(非跨網段專用通訊軟體)能相互通訊么?不能。這是為什麼呢?因為區域網路中也使用TCP/IP協定,而TCP/IP協定中常用的基礎協定TCP和UDP都使用子網掩碼這個東東。所以如果你們的子網不是相互包含,那么你們通訊時所傳送的數據包將被無情的丟棄。那我用廣播通訊不行么? 當然行啦,不過廣播通信會增加其他非參與者的負荷。如果使用多播,多播通訊編程難么? 我原來也以為很難,呵呵,現在我可不那么認為了,下面是多播通訊類的代碼。
//Multicast.c
#pragma once
// auth: YYcYY
// date: 2006-8-12
// copyright: All free
//定義收到數據時通知父視窗的訊息編號:WM_MUC_RECEIVE_DATA
#define WM_MUC_RECEIVE_DATA (WM_USER + 1097)
#define MAX_MUC_PACKET_SIZE 1460
#define SEND_BUFF_COUNT 4
#define RECEIVE_BUFF_COUNT 32
#define MU_PORT 5201
#define MU_GROUP_IP "224.0.0.8"
const int PACKET_HEAD_SIZE = 20;
#define MSG_TYPE_ALLUSER 1
#define MSG_TYPE_ACK 2
#define MSG_TYPE_ONLINE 3
#define MSG_TYPE_PROXY_REQUEST 4 //特殊用途#define MSG_TYPE_ONEUSER 5
struct SPACKET
{
char used;
char nType;
long long time;
int nUnused;
char data[MAX_MUC_PACKET_SIZE-20];
};
// CMulticast 命令目標
class CMulticast : public CAsyncSocket
{
private:
CWnd * m_pParent;
SOCKADDR_IN m_GroupAddr;
ip_mreq m_mrMReq;
int m_nTTL;
CString m_sLocalIP;
public:
CMulticast(CWnd * pParent, CString & localIP);
virtual ~CMulticast();
virtual void OnReceive(int nErrorCode);
BOOL InitSock(void);
void DeleteThis();
int SendData(int nIndex, int len);
SPACKET SendBuff[SEND_BUFF_COUNT];
SPACKET ReveiveBuff[RECEIVE_BUFF_COUNT];
SPACKET AckBuff;
};
// Multicast.cpp : 實現檔案
//
#include "stdafx.h"
#include "Multicast.h"
#include ".\multicast.h"
// CMulticast
CMulticast::CMulticast(CWnd * pParent, CString & localIP)
{
m_pParent = pParent;
m_sLocalIP = localIP; //如果不設定請使用空字元串
m_nTTL = 3; //允許經過的路由個數
// 初試化個個成員變數
memset(&m_mrMReq, 0, sizeof(m_mrMReq));
memset(&m_GroupAddr, 0, sizeof(m_GroupAddr));
memset(ReveiveBuff, 0, sizeof(SPACKET)* RECEIVE_BUFF_COUNT);
memset(SendBuff, 0, sizeof(SPACKET)* SEND_BUFF_COUNT);
// 使用函式初始化 否則容易產生記憶體錯誤
InitSock();
}
CMulticast::~CMulticast()
{
// 使用函式析構 否則容易產生記憶體錯誤
DeleteThis();
}
void CMulticast::DeleteThis()
{
// 離開多播組
setsockopt (m_hSocket, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char FAR *)&m_mrMReq, sizeof(m_mrMReq));
}
// CMulticast 成員函式
void CMulticast::OnReceive(int nErrorCode)
{
// TODO: 在此添加專用代碼和/或調用基類
int i=0,len=0;
UINT nPort = 0;
CString * pStr = new CString; // 由使用者使用完後釋放。
for (i=0;i<RECEIVE_BUFF_COUNT;i++)
{
if (ReveiveBuff[i].used == 0)
{
break;
}
}
len = ReceiveFrom(&ReveiveBuff[i], MAX_MUC_PACKET_SIZE, *pStr, nPort);
if (len > 0)
{ //通知父視窗,訊息第一個參數 i 為接收到的訊息在緩衝區的索引值
::PostMessage(m_pParent->GetSafeHwnd(), WM_MUC_RECEIVE_DATA, (WPARAM)i, (LPARAM)pStr);
}
CAsyncSocket::OnReceive(nErrorCode);
}
BOOL CMulticast::InitSock(void)
{ //創建 Socket 並綁定地址為 m_sLocalIP
if(!Create(MU_PORT, SOCK_DGRAM, FD_READ,m_sLocalIP))
return FALSE;
BOOL bMultipleApps = TRUE; /* 允許復用連線埠*/
SetSockOpt(SO_REUSEADDR, (void*)&bMultipleApps, sizeof(BOOL), SOL_SOCKET);
/* 填寫 m_GroupAddr 的欄位值 */
memset(&m_GroupAddr, 0, sizeof(m_GroupAddr));
m_GroupAddr.sin_family = AF_INET;
m_GroupAddr.sin_addr.s_addr = inet_addr(MU_GROUP_IP);
m_GroupAddr.sin_port = htons((USHORT)MU_PORT);
/* 加入多播組 */
m_mrMReq.imr_multiaddr.s_addr = inet_addr(MU_GROUP_IP); /* 多播組地址 */
m_mrMReq.imr_interface.s_addr = inet_addr(m_sLocalIP); /* 要使用的本地地址,需要與 綁定的地址相同*/
if(setsockopt(m_hSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char FAR *)&m_mrMReq, sizeof(m_mrMReq)) < 0)
return FALSE;
/* 設定 TTL 值,與跨越的路由設備個數相關,一般不要設定太大 1-127 */
if(SetSockOpt(IP_MULTICAST_TTL, &m_nTTL, sizeof(int), IPPROTO_IP) == 0)
return FALSE; /* 設定 TTL 發生錯誤 */
return TRUE;
}
int CMulticast::SendData(int nIndex, int len)
{
if (nIndex == -1)
{ // 傳送確認數據
return SendTo(&AckBuff, len, MU_PORT, MU_GROUP_IP);
}
if (nIndex >= SEND_BUFF_COUNT || nIndex < 0)
{
return 0;
}
return SendTo(&SendBuff[nIndex], len, MU_PORT, MU_GROUP_IP);
}
使用這個多播類,就像使用一般的UDP套接字一樣。
傳送數據 默認使用 索引為0的緩衝區
SPACKET * pak = &m_pMuSock->SendBuff[0];
int len = str.GetLength();
pak->used = 1;
pak->nType = MSG_TYPE_ONEUSER;
pak->nUnused = 0;
pak->time= CTime::GetCurrentTime().GetTime();
strncpy(pak->data, str, len);
pak->data[len] = 0;
pak->nUnused = inet_addr(*pStr);
m_pMuSock->SendData(i, len + PACKET_HEAD_SIZE +1);
接收數據 在 DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) 中添加
LRESULT CTestDlg::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// TODO: 在此添加專用代碼和/或調用基類
SPACKET * pak;
CString * psIP;
switch(message)
{
case WM_MUC_RECEIVE_DATA:
pak = &m_pMuSock->ReveiveBuff[wParam];
psIP = (CString *)lParam;
case WM_MUC_RECEIVE_DATA:
pak = &m_pMuSock->ReveiveBuff[wParam];
psIP = (CString *)lParam;
if (pak->nType == MSG_TYPE_ALLUSER)
{
//處理訊息
}
delete psIP;
pak->used = 0;
break;
}