一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

網(wǎng)絡(luò)傳輸

 liang1234_ 2019-04-13

http://www.cnblogs.com/my_life/articles/4943353.html

http://www./tonykee/archive/2008/02/17/42829.aspx

http://www.cnblogs.com/foohack/p/4718320.html 

 

網(wǎng)絡(luò)數(shù)據(jù)傳輸,可以直接發(fā)送字符串,但不能直接發(fā)送一個(gè)結(jié)構(gòu)體。

網(wǎng)絡(luò)上傳輸數(shù)據(jù),因?yàn)榘l(fā)送端和接收端,通常不能保證是兩邊是相同的編程語言,就算都是使用C語言,CPU字節(jié)序,或者CPU位數(shù)不一樣,直接將結(jié)構(gòu)體的數(shù)據(jù)整理成流發(fā)送過去,數(shù)據(jù)排序或者長(zhǎng)度會(huì)跟你想象的不一樣。解釋起來比較費(fèi)篇幅。

這里說下通常的解決辦法:

  • 約定一個(gè)協(xié)議,協(xié)議規(guī)定好數(shù)據(jù)流中每個(gè)字節(jié)的含義
  • 發(fā)送端要保證按照協(xié)議要求組裝好數(shù)據(jù)流。
  • 接收端按照協(xié)議規(guī)定讀取出里面的數(shù)據(jù)(解析)。

 

http://www.cnblogs.com/kaijia9/p/3394953.html

UDP傳輸模式是數(shù)據(jù)報(bào),TCP傳輸模式為字節(jié)流,字節(jié)流與數(shù)據(jù)報(bào)區(qū)別在于有邊界與無邊界。例如:TCP客戶端發(fā)送了三個(gè)數(shù)據(jù)包,開的緩存足夠大服務(wù)端一次可接收三個(gè)數(shù)據(jù)包的數(shù)據(jù),這就是無邊界。UDP客戶端發(fā)送了三個(gè)數(shù)據(jù)包,就算開的緩存足夠大服務(wù)端一次也只能接收一個(gè)數(shù)據(jù)包,這就是有邊界。

還有就是協(xié)議會(huì)維護(hù)源地址和目的地址直到協(xié)議要求斷開連接,這就決定了TCP不能進(jìn)行廣播和多播。

 

直接發(fā)送結(jié)構(gòu)體的方式【是不對(duì)的】:

·     char send_buf[1024] = "tony  2000  ";  

·     memset(send_buf,0,1024);  

·     struct msg  

·     {  

·         int cmd;  

·         int sendID;  

·         int recvID;  

·         string name;  

·         int number;  

·     };  

·     msg msg1;  

·     msg1.cmd = COMMAND;  

·     msg1.sendID = 2120100324;  

·     msg1.recvID = 2120100325;  

·     msg1.name = "Tony";  

·     msg1.number = 2000;  

·       

·     //memcpy(send_buf,&msg1,sizeof(msg));  

·     //int len_send = send(Socket,send_buf,sizeof(send_buf),0);  

·     int len_send = send(Socket,(char *)&msg1,sizeof(msg),0);  

如上所示,

TCP是無邊界的字節(jié)流傳輸,所以需要將結(jié)構(gòu)體轉(zhuǎn)換為字符串后在發(fā)送,最后三行用了兩種方法發(fā)送屬于結(jié)構(gòu)體類型的數(shù)據(jù),通過TCP傳輸。最后在接收方需要轉(zhuǎn)換為結(jié)構(gòu)體。

紅色:  數(shù)組屬于字符串,該方法是將要發(fā)送結(jié)構(gòu)體所占字節(jié)大小考到數(shù)組中,       再通過數(shù)組發(fā)送。

藍(lán)色:  將該結(jié)構(gòu)體地址轉(zhuǎn)化為char* 類型的地址,目的是使該指針加1移動(dòng)時(shí) 是按一個(gè)字節(jié)移動(dòng),而不是加1按該結(jié)構(gòu)體大小移動(dòng),然后發(fā)送該結(jié)構(gòu) 體所占字節(jié)大小

 

 

struct AP_INFO { 
  char action; 
  char *test; 
  char *testlist; 
  }; 
這樣定義的結(jié)構(gòu)更是不能直接傳輸?shù)模?span style="color: #ff0000;">因?yàn)槠渲杏袃蓚€(gè)是指針,指向的是結(jié)構(gòu)以外的內(nèi)存地址,通過socket傳輸?shù)綄?duì)方機(jī)器后無法解析,搞得不好的話甚至可能造成程序崩潰! 

原始的序列化:將結(jié)構(gòu)體的成員一個(gè)一個(gè)的復(fù)制到內(nèi)存再發(fā)到服務(wù)端

 

 

===============================================

http://www.cnblogs.com/foohack/p/4718320.html

大家都知道,在進(jìn)行網(wǎng)絡(luò)傳輸?shù)臅r(shí)候,因?yàn)榉植荚诰W(wǎng)絡(luò)上的每臺(tái)機(jī)器可能大小端的不同,需要進(jìn)行字節(jié)序列轉(zhuǎn)換,比如用win32 API的socket里面就有類似與htonl等與此類似的函數(shù),它就是把主機(jī)端的字節(jié)序列轉(zhuǎn)換成網(wǎng)絡(luò)傳輸?shù)淖止?jié)序列。當(dāng)然也有與之相反的函數(shù)ntohl,是把網(wǎng)絡(luò)字節(jié)序,轉(zhuǎn)換為主機(jī)字節(jié)序。

 

比如 int data = 0x32461256在小端機(jī)器上按照“高高低低”的原則,內(nèi)存上是這樣表示,0x56,0x12,0x46,0x32。進(jìn)行htonl轉(zhuǎn)換后,在內(nèi)存中的布局就會(huì)變成0x32,0x46,0x12,0x56。

 

所以,我們通過socket的send發(fā)送結(jié)構(gòu)體或者對(duì)象的時(shí)候要注意了,需要序列化,當(dāng)然,大家可以說,這樣一個(gè)結(jié)構(gòu)體那么多字段都要手動(dòng)用htonl之類的函數(shù)序列化,那么太麻煩,其實(shí)網(wǎng)絡(luò)上有專門的序列化庫(kù),比如google的protobuff,boost也有相應(yīng)模塊,Qt的QDataStream內(nèi)部就實(shí)現(xiàn)了序列化,序列化實(shí)際上就是把大小端,還有結(jié)構(gòu)體字節(jié)對(duì)齊等細(xì)節(jié)屏蔽了。所以,一般通過send發(fā)送結(jié)構(gòu)體不能直接把它轉(zhuǎn)換成char*的字節(jié)序列發(fā)送,在發(fā)送之前,要先做序列化

 

以下給出用Qt的QDataStream做序列化例子:

http://www./Code/Cpp/Qt/SerializationwithQDataStream.htm

http://comments./gmane.comp.lib.qt.general/38559

 

 注意:char型的數(shù)據(jù)是不用序列化的,因?yàn)橹皇菃蝹€(gè)字節(jié),不是多字節(jié)占用

references:

http:///questions/5894622/sending-any-structure-via-qtcpsocket

http:///questions/2473300/overloading-the-qdatastream-and-operators-for-a-user-defined-type

http:///questions/1577161/passing-a-structure-through-sockets-in-c

http:///questions/17817280/send-struct-over-socket-in-c

 

 

=======================

http://hcq0618.blog.163.com/blog/static/1780903512013101831120514/

 

主要技術(shù)問題:windows,linux等系統(tǒng)采用LITTLE_ENDIAN字節(jié)序,而java自身采用BIG_ENGIAN字節(jié)序,BIG_ENGIAN是指低地址存放最高有效字節(jié)(MSB),而LITTLE_ENDIAN則是低地址存放最低有效字節(jié)Java程序?qū)懙目蛻舫绦蚨送琧++的服務(wù)端程序交互時(shí)結(jié)構(gòu)體的某些數(shù)據(jù)類型需要轉(zhuǎn)換字節(jié)序。本文解決方法,java客戶端程序發(fā)送數(shù)據(jù)時(shí)做相應(yīng)的轉(zhuǎn)換字節(jié)序,等收到數(shù)據(jù)時(shí)再做一次字節(jié)序的轉(zhuǎn)換。

現(xiàn)在的網(wǎng)絡(luò)程序多數(shù)采用可靠交付的TCP協(xié)議,其采用字節(jié)流的傳輸方式,c++程序中用結(jié)構(gòu)體來模擬報(bào)頭以此界定每次發(fā)送的報(bào)文。所以網(wǎng)絡(luò)中整個(gè)字節(jié)流的格式:報(bào)頭+數(shù)據(jù)負(fù)載+報(bào)頭+數(shù)據(jù)負(fù)載……

 

 c++與java進(jìn)行socket通信時(shí)注意事項(xiàng)

    因?yàn)?span style="color: #ff0000;">java發(fā)送的都是網(wǎng)絡(luò)字節(jié)序(big-endium),而c++是主機(jī)字節(jié)序(little-endium),所以當(dāng)消息中有整型,浮點(diǎn)型(應(yīng)盡量避免使用)的時(shí)候需要用htonl,htons,ntohl,ntohs等函數(shù)轉(zhuǎn)換一下,字符串由于是單字節(jié)排序的不需要轉(zhuǎn)換,但應(yīng)注意c++字符串是以'/0'作為結(jié)束符的,如果找不到'/0'可能會(huì)出現(xiàn)一些亂碼,所以接收的時(shí)候可以分配一個(gè)length+1的buffer用來接收消息(貌似java會(huì)自動(dòng)處理).   

網(wǎng)絡(luò)只有字節(jié)的概念,所以,你必須把你要傳送的東西全部轉(zhuǎn)換成字節(jié)后,再發(fā)送出去,在c中,以字節(jié)方式存在的數(shù)據(jù),是不需要進(jìn)行轉(zhuǎn)換的,比如char *什么的

 

可參考qiyi的ChatMsg.h中的序列化函數(shù):對(duì)單字節(jié)字段【char, char *, char [], 可當(dāng)作char*的string等】都沒做大小端轉(zhuǎn)換,對(duì)其他的short, int, long等都需要大小端轉(zhuǎn)換

 

short 或者 long的數(shù)據(jù)在進(jìn)行通信的時(shí)候最好養(yǎng)成:

1、發(fā)送的時(shí)候使用:htons(l)
2、接受的時(shí)候使用:ntohs(l)
當(dāng)然了一般我都不用int型的數(shù)據(jù)通信,從來都是字符串通信,發(fā)送方利用sprintf組織,接收方利用atoi進(jìn)行轉(zhuǎn)換~~ 

http:///unp/2015/10/15/unp-socket/

在《Linux高性能服務(wù)器編程》中這里理解更好些:

現(xiàn)代PC大多采用小端字節(jié)序,因此小端字節(jié)序又稱為主機(jī)字節(jié)序。

當(dāng)格式化的數(shù)據(jù)(比如32 bit整型數(shù)和16 bit短整型數(shù))在兩臺(tái)使用不同字節(jié)序的主機(jī)之間直接傳遞時(shí),接收端必然錯(cuò)誤地解釋之。解決問題的方法是:發(fā)送端總是把要發(fā)送的數(shù)據(jù)轉(zhuǎn)化成大端字節(jié)序數(shù)據(jù)后再發(fā)送,而接收端知道對(duì)方傳送過來的數(shù)據(jù)總是采用大端字節(jié)序【因?yàn)榫W(wǎng)絡(luò)序是大端】,所以接收端可以根據(jù)自身采用的字節(jié)序決定是否對(duì)接收到的數(shù)據(jù)進(jìn)行轉(zhuǎn)換(小端機(jī)轉(zhuǎn)換,大端機(jī)不轉(zhuǎn)換)。因此大端字節(jié)序也稱為網(wǎng)絡(luò)字節(jié)序,它給所有接收數(shù)據(jù)的主機(jī)提供了一個(gè)正確解釋收到的格式化數(shù)據(jù)的保證。

知道為什么有模式的存在,下面需要了解應(yīng)用場(chǎng)景:

1、不同端模式的處理器進(jìn)行數(shù)據(jù)傳遞時(shí)必須要考慮端模式的不同

2、在網(wǎng)絡(luò)上傳輸數(shù)據(jù)時(shí),由于數(shù)據(jù)傳輸?shù)膬啥藢?duì)應(yīng)不同的硬件平臺(tái),采用的存儲(chǔ)字節(jié)順序可能不一致。所以在TCP/IP協(xié)議規(guī)定了在網(wǎng)絡(luò)上必須采用網(wǎng)絡(luò)字節(jié)順序,也就是大端模式, 對(duì)于char型數(shù)據(jù)只占一個(gè)字節(jié),無所謂大端和小端。而對(duì)于非char類型數(shù)據(jù),必須在數(shù)據(jù)發(fā)送到網(wǎng)絡(luò)上之前將其轉(zhuǎn)換成大端模式。接收網(wǎng)絡(luò)數(shù)據(jù)時(shí)按符合接受主機(jī)的環(huán)境接收。

 

struct {
    char one;    //字符
    unsigned short two;  //short類型
    unsigned int three;    //int類型
    char * four;    //字符串

}BinaryProtocolStruct;

//one為char類型不需要進(jìn)行網(wǎng)絡(luò)主機(jī)傳輸模式轉(zhuǎn)換,把one的值寫入到內(nèi)存塊中
//two為unsigned short 類型,所以要進(jìn)行網(wǎng)絡(luò)主機(jī)的傳輸字節(jié)順序的轉(zhuǎn)換 htons
//three 為int類型 所以要進(jìn)行網(wǎng)絡(luò)主機(jī)的傳輸字節(jié)順序的轉(zhuǎn)換 htonl
//four為字符串不需要進(jìn)行存儲(chǔ)轉(zhuǎn)換

 

主機(jī)字節(jié)序與網(wǎng)絡(luò)字節(jié)序 
主機(jī)字節(jié)序 
不同的CPU有不同的字節(jié)序類型 這些字節(jié)序是指整數(shù)在內(nèi)存中保存的順序 這個(gè)叫做主機(jī)序  
最常見的有兩種 
1. Little endian:將低序字節(jié)存儲(chǔ)在起始地址 
2. Big endian:將高序字節(jié)存儲(chǔ)在起始地址 

網(wǎng)絡(luò)字節(jié)序 
網(wǎng)絡(luò)字節(jié)順序是TCP/IP中規(guī)定好的一種數(shù)據(jù)表示格式,它與具體的CPU類型、操作系統(tǒng)等無關(guān),從而可以保證數(shù)據(jù)在不同主機(jī)之間傳輸時(shí)能夠被正確解釋。網(wǎng)絡(luò)字節(jié)順序采用big endian排序方式。 

同樣 在網(wǎng)絡(luò)程序開發(fā)時(shí) 或是跨平臺(tái)開發(fā)時(shí) 也應(yīng)該注意保證只用一種字節(jié)序 不然兩方的解釋不一樣就會(huì)產(chǎn)生bug. 

Java 程序與 C++ 之間的 SOCKET 通訊 
4.1 字節(jié)序問題 
一直以來都在進(jìn)行著C++ 上面的網(wǎng)絡(luò)開發(fā),發(fā)現(xiàn)在 C++ 上面進(jìn)行通訊的時(shí)候,基本上都沒有考慮到網(wǎng)絡(luò)字節(jié)序的問題,特別是網(wǎng)絡(luò)應(yīng)用中的用戶數(shù)據(jù)。大家都知道網(wǎng)絡(luò)通訊傳輸?shù)亩际亲止?jié)流的數(shù)據(jù),于是都是定義一個(gè) char 類型的緩沖區(qū),然后不管 int , WORD, DWORD 還是其他自定義類型的結(jié)構(gòu)對(duì)象也好,都直接 memcpy() 拷貝到緩沖區(qū),直接發(fā)送出去了,根本都沒有考慮所傳輸數(shù)據(jù)的網(wǎng)絡(luò)字節(jié)序問題。如果非要說一點(diǎn)關(guān)注了網(wǎng)絡(luò)字節(jié)序問題的話,那就是有一個(gè)地方,大家都回去用到的,也就是網(wǎng)絡(luò)通訊端口,把端口號(hào)賦值給 sockaddr_in .sin_port之時(shí)大家都會(huì)使用了htons() ,也就是把端口號(hào)從主機(jī)字節(jié)序轉(zhuǎn)化為網(wǎng)絡(luò)字節(jié)序。 
因?yàn)檫@些程序的服務(wù)器端也好,客戶端也好,都是在x86 系列系統(tǒng)下運(yùn)行,并且都是 C++ 編譯出來的,所以不會(huì)因?yàn)樽止?jié)序而出現(xiàn)問題。 
現(xiàn)在所做項(xiàng)目,涉及到Java 與 C++ 之間的 SOCKET 通訊,這樣的情況下,就需要大家都按規(guī)則來辦事了, C++ 方面?zhèn)鬏數(shù)亩嘧止?jié)類型數(shù)據(jù)還請(qǐng)從主機(jī)字節(jié)序轉(zhuǎn)化成網(wǎng)絡(luò)字節(jié)序再進(jìn)行傳輸。 
當(dāng)然,數(shù)據(jù)是由程序員來組合的,也是由程序員來解析的,所以如果不按標(biāo)準(zhǔn)行事也是可以的。但是就需要在解析數(shù)據(jù)的時(shí)候注意好了。 
建議還是按標(biāo)準(zhǔn)行事,把數(shù)據(jù)轉(zhuǎn)化成網(wǎng)絡(luò)字節(jié)序。 
     PS: 
     Java與 Windows 平臺(tái)下其他開發(fā)語言之間進(jìn)行數(shù)據(jù)交與,也需要遵循該原則; 
     Java下讀寫 Windows 平臺(tái)下其他開發(fā)語言保存的數(shù)據(jù),或是 Windows 平臺(tái)下其他語言讀寫Java 保存的數(shù)據(jù),也需要注意字節(jié)序問題。

 

byte,string區(qū)別:本來以為傳輸?shù)臅r(shí)候就是string類型字符串,原來根本不是一回事。網(wǎng)絡(luò)上傳輸數(shù)據(jù)都是字節(jié)碼,就是我們常說的 ascII碼的,對(duì)應(yīng)到類型上就是byte類型的。而string只是java中一種對(duì)象而已。而且java中編碼一般是unicode編碼的,要進(jìn)行和byte類型的轉(zhuǎn)化。int和long類型的也要進(jìn)行int2byte轉(zhuǎn)化。

接收到數(shù)據(jù)之后,則要進(jìn)行byte2int轉(zhuǎn)化。且值得注意的是int轉(zhuǎn)成byte并不是直接字符串的轉(zhuǎn)化,比如123轉(zhuǎn)成字符串就是123,但是轉(zhuǎn)成byte就不是了。它要根據(jù)整數(shù)123所占的字節(jié),得到每個(gè)字節(jié)的值,再轉(zhuǎn)成byte數(shù)組。常用的轉(zhuǎn)化函數(shù)有:

//int2byte

public static byte[] intToByte(int n) {

        byte[] b = new byte[4];

        b[0] = (byte) (n >> 24);

        b[1] = (byte) (n >> 16);

        b[2] = (byte) (n >> 8);

        b[3] = (byte) (n);

        return b;

    }

 

    public static void int2byte(int n, byte buf[], int offset) {

        buf[offset] = (byte) (n >> 24);

        buf[offset 1] = (byte) (n >> 16);

        buf[offset 2] = (byte) (n >> 8);

        buf[offset 3] = (byte) n;

    }

 

    // 字節(jié)類型轉(zhuǎn)成int類型

    public static int byte2int(byte b[]) {

        return b[3] & 0xff | (b[2] & 0xff) << 8 | (b[1] & 0xff) << 16

                | (b[0] & 0xff) << 24;

    }

//short2byte

public static byte[] short2byte(int n) {

        byte b[] = new byte[2];

        b[0] = (byte) (n >> 8);

        b[1] = (byte) n;

        return b;

    }

// long到byte的轉(zhuǎn)換

    public static byte[] long2byte(long n) {

        byte b[] = new byte[8];

        b[0] = (byte) (int) (n >> 56);

        b[1] = (byte) (int) (n >> 48);

        b[2] = (byte) (int) (n >> 40);

        b[3] = (byte) (int) (n >> 32);

        b[4] = (byte) (int) (n >> 24);

        b[5] = (byte) (int) (n >> 16);

        b[6] = (byte) (int) (n >> 8);

        b[7] = (byte) (int) n;

        return b;

    }

等等,注意:這里只是進(jìn)行普通的字節(jié)碼和數(shù)值之間的類型轉(zhuǎn)換,并不進(jìn)行高低位轉(zhuǎn)化。原因前面已經(jīng)說過了,java和網(wǎng)絡(luò)字符是一樣的,都是高位前,低位后,所以不用進(jìn)行轉(zhuǎn)化。

 

中文傳輸問題:

網(wǎng)絡(luò)中傳輸中文極易出現(xiàn)亂碼,那怎么辦比較好呢,對(duì)了,就是對(duì)中文進(jìn)行編碼,常用的是Base64編碼。再對(duì)編碼后數(shù)據(jù)進(jìn)行傳輸,接收到后也要先進(jìn)行base64解碼即可。

 

==================================================

http://www./html/26616.html

struct A
{
  int id;
  string msg;
};

不建議發(fā)結(jié)構(gòu)體,因?yàn)?span style="color: #ff0000;">即便雙方采用同樣的語言和編譯器,也可能因?yàn)樘畛渥止?jié)的不同而導(dǎo)致結(jié)構(gòu)體計(jì)算的大小不同。建議嚴(yán)格規(guī)定各個(gè)字段的大小和意義,依次發(fā)送。寫到byte[]發(fā)送。

 

=============================

 

雖然,網(wǎng)絡(luò)編程里面的數(shù)據(jù)傳送推薦用序列化,但我不用,還是選擇結(jié)構(gòu)體(返璞歸真),有以下幾點(diǎn)理由:
1.跨平臺(tái)問題:
  序列化確實(shí)可以很好的跨語言平臺(tái),可大多數(shù)網(wǎng)絡(luò)游戲不需要跨語言平臺(tái)

2.別以為有了序列化就不需要結(jié)構(gòu)體
  表面上序列化代碼量小,按順序讀和寫char int, short LPCSTR ... 就好,邏輯對(duì)象寫不寫都無所謂,那就是大錯(cuò)而特錯(cuò)了
  待序列化的對(duì)象/發(fā)送前的結(jié)構(gòu)還是不可省略的。序列化的過程就是 object->(按一定順序拆分)write->bytes->(按拆分順序組裝)read->object的過程
 其實(shí)object還是不能省略,很多人寫網(wǎng)絡(luò)程序不注重邏輯對(duì)象結(jié)構(gòu),收到的一堆bytes按一定順序讀和寫就完事了,這樣雖然靈活,但缺乏結(jié)構(gòu),容易造成混亂,調(diào)試起來是災(zāi)難【ulu的設(shè)備代碼就是這樣的,其實(shí)這就是最基礎(chǔ)原始的序列化】
   所以結(jié)構(gòu)體(或類)還是省略不了的,所以:別以為有了序列化,就不需要結(jié)構(gòu)體了。

3.結(jié)構(gòu)體存在內(nèi)存對(duì)齊和CPU不兼容的問題,可以避免
  的確結(jié)構(gòu)體是有內(nèi)存對(duì)齊的問題,存在兼容性問題,我可以選擇pack(1)把內(nèi)存對(duì)齊給關(guān)閉掉,避免兼容性問題,既然選擇了iocp就不打算跨平臺(tái)了,可以避免結(jié)構(gòu)體平臺(tái)兼容的問題

4.結(jié)構(gòu)體調(diào)試起來方便很多,減少內(nèi)存拷貝,效率高
  不用序列化write和read的過程就不需要過多考慮(少寫太多代碼了),read write 就好像現(xiàn)代社會(huì)每個(gè)人每天都要穿衣服和脫衣服一樣,原始社會(huì)需要嗎?其實(shí)人類進(jìn)化到原始裸奔狀態(tài)才是最爽快的:)
  但還是要說句公道話:有人說序列化編碼解碼read write 需要耗費(fèi)資源, 誠(chéng)然這個(gè)過程基本等于賦值和內(nèi)存拷貝,那點(diǎn)效率損失主要還在內(nèi)存拷貝上,這點(diǎn)效率損失很小,不能作為序列化的缺點(diǎn),當(dāng)然如果涉及到數(shù)據(jù)加密那將是另外一個(gè)話題

5.結(jié)構(gòu)體貌似呆板,發(fā)送數(shù)據(jù)限制多,發(fā)送變長(zhǎng)數(shù)據(jù)就不方便,數(shù)據(jù)組織起來也不靈活
  我想這是很多人拋棄結(jié)構(gòu)體,選擇用序列化方式發(fā)送和接受數(shù)據(jù)的一個(gè)很重要的原因
  但:其實(shí)對(duì)于變長(zhǎng)結(jié)構(gòu)(子結(jié)構(gòu)也是變長(zhǎng))的問題,用結(jié)構(gòu)體來實(shí)現(xiàn)的確很麻煩,但并不代表不能實(shí)現(xiàn)
  我已經(jīng)實(shí)現(xiàn)了,而且讀和寫變長(zhǎng)子結(jié)構(gòu)體嵌套任意多層都不成問題,可以存儲(chǔ)復(fù)雜變長(zhǎng)的數(shù)據(jù)結(jié)構(gòu),
  數(shù)據(jù)就如同能自動(dòng)序列化一樣方便,這個(gè)應(yīng)該是技術(shù)難點(diǎn),但細(xì)心去做是可以實(shí)現(xiàn)的

6.關(guān)于結(jié)構(gòu)體指針
  游戲里面要發(fā)送的數(shù)據(jù)內(nèi)存事先分配好的,不存在指針,深度復(fù)制更不用考慮,所以內(nèi)存拷貝不會(huì)出錯(cuò)
  如果用到指針即使用序列化來實(shí)現(xiàn)也會(huì)面臨同樣的問題也占不了多少便宜,由于C++這們語言的特點(diǎn),
  不象java那樣有個(gè)標(biāo)準(zhǔn)實(shí)現(xiàn),對(duì)于序列化本身沒有一個(gè)統(tǒng)一的標(biāo)準(zhǔn),所以可想而知,有人說:boost有它的序列化的實(shí)現(xiàn)
  其實(shí)那個(gè)實(shí)現(xiàn)不見得就合適你自己,如果真要做序列化,編碼和解碼得仿照那個(gè)過程自己寫才最為牢靠,
  哪些指針對(duì)應(yīng)的內(nèi)存需要序列化那些不需要序列化,是個(gè)邏輯結(jié)構(gòu),需要自己說了算才好(好像扯遠(yuǎn)了點(diǎn))
  說回游戲數(shù)據(jù),既然不用需要他用到指針,結(jié)構(gòu)體用來發(fā)送數(shù)據(jù)也沒問題的

7 平臺(tái)擴(kuò)充問題
  退一萬步的說:換了語言就基本上換了客戶端,客戶端的數(shù)據(jù)組織形式都要重寫
  實(shí)在不行還可以考慮用xml json 編碼等等一些跨平臺(tái)的解決方案,現(xiàn)在所寫的結(jié)構(gòu)體是可以用來做數(shù)據(jù)接收的,只是發(fā)送的不再是結(jié)構(gòu)體而已

8.綜上所述
  如果需要跨語言平臺(tái),不用序列化(二進(jìn)制流或xml, json文本等等)根本無法實(shí)現(xiàn)
  序列化的優(yōu)點(diǎn)還是非常多的.如果主要是跨平臺(tái)和語言自定義讀寫規(guī)則,根據(jù)需要讀寫對(duì)象的某一部分?jǐn)?shù)據(jù),
  空間浪費(fèi)少,不存在內(nèi)存對(duì)齊問題等諸多優(yōu)點(diǎn),缺點(diǎn)就是拐彎抹角,代碼量大,調(diào)試不方便

最好的方法還是模擬rpc的解決方案,利用idl解析器自動(dòng)生成序列化,只是這需要用lex/yacc方面的咚咚, 
tao,ice等都有原代碼可借鑒。

 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    亚洲欧美日韩国产综合在线| 欧美日韩乱一区二区三区| 日本人妻精品中文字幕不卡乱码| 亚洲第一区欧美日韩在线| 欧美日韩国产成人高潮| 欧美黑人暴力猛交精品| 中文字幕精品一区二区三| 空之色水之色在线播放| 日本丁香婷婷欧美激情| 国产亚洲欧美自拍中文自拍| 国产又色又粗又黄又爽| 中日韩美一级特黄大片| 欧美二区视频在线观看| 国产精品不卡高清在线观看| 欧美精品激情视频一区| 色哟哟在线免费一区二区三区| 午夜日韩在线观看视频| 少妇人妻无一区二区三区| 五月的丁香婷婷综合网| 亚洲高清亚洲欧美一区二区| 国产一级片内射视频免费播放| av中文字幕一区二区三区在线| 国产国产精品精品在线| 亚洲中文字幕乱码亚洲| 欧美在线视频一区观看| 亚洲av一区二区三区精品| 午夜福利视频六七十路熟女| 欧美日韩综合免费视频| 黄色片一区二区在线观看| 欧洲日本亚洲一区二区| 欧美极品欧美精品欧美| 91在线爽的少妇嗷嗷叫| 日韩中文字幕人妻精品| 亚洲一区二区三区四区| 办公室丝袜高跟秘书国产| 日本91在线观看视频| 东京热电东京热一区二区三区| 老司机激情五月天在线不卡| 日系韩系还是欧美久久| 亚洲精品熟女国产多毛| 激情视频在线视频在线视频|