C 技術參考 Socket傳輸結構資料

2022-04-10 14:49:54 字數 4606 閱讀 9444

最近在做乙個機械人專案,要實時的接收機械人傳回的座標資訊,並在客戶端顯示當前的地圖和機械人的位置。當然座標的回傳是用的socket,用的是c++的結構體表示的座標資訊。但是c#不能像c++那樣很easy的把位元組陣列byte直接的轉換成結構,來傳送和接收。在c#中要多做一些工作。但是在c或者c++中這是一件很容易的事,只需要乙個函式:

void *memcpy(void *dest, const void *src, size_t n);//從源src所指的記憶體位址的起始位置開始拷貝n個位元組到目標dest所指的記憶體位址的起始位置中
下面來完成通過c#實現socket傳輸結構資料。

1. 仿照c++的結構寫出c#的結構體來:為了便於復用,把它放在乙個單獨類裡面

public class socketstruct

//建構函式

}//struct

}

2. 既然要接收c++傳送過來的資料,就要注意c#和c++資料型別的對應關係:

c++與c#的資料型別對應關係表:

所以上面定義的整個結構的位元組數是22個bytes.

注意區分上面的位元組和字元。計算機儲存容量基本單位是位元組(byte),8個二進位制位組成1個位元組,乙個標準英文本母佔乙個位元組位置,乙個標準漢字佔二個位元組位置。字元是一種符號,同儲存單位不是一回事,它是一種抽象的、邏輯的型別,與int等一樣。byte是物理的單位。

對應的c++結構體是:

typedef struct

operator;

3. 在傳送資料時,要先把結果轉換成位元組陣列,在接收到資料之後要把位元組陣列還原成原本的結構。具體的**如下,為了便於復用,寫成乙個類:

public class bytesandstruct

//structtobytes

/// /// byte陣列轉換為結構

///

/// byte陣列

/// 結構型別

/// 轉換後的結構

public static object bytestostruct(byte bytes, type type)

//分配結構大小的記憶體空間

intptr structptr = marshal.allochglobal(size);

//將byte陣列拷貝到分配好的記憶體空間

marshal.copy(bytes, 0, structptr, size);

//將記憶體空間轉換為目標結構

object obj = marshal.ptrtostructure(structptr, type);

//釋放記憶體空間

marshal.freehglobal(structptr);

//返回結構

return obj;}}

這是個工具類,裡面的方法都是靜態的。

寫一點注意的技巧:

在結構轉換成位元組資料的時候,要把結構的型別作為引數傳遞到函式中去,所以函式接收的引數是乙個型別。這時用到了c#中的type類。

c#中通過type類可以訪問任意資料型別資訊。

1.獲取給定型別的type引用有3種方式:

a.使用typeof運算子,如type t = typeof(int);

b.使用gettype()方法,如int i;type t = i.gettype();

c.使用type類的靜態方法gettype(),如type t =type.gettype("system.double");

2.type的屬性:

name:資料型別名;

fullname:資料型別的完全限定名,包括命名空間;

namespace:資料型別的命名空間;

basetype:直接基本型別;

underlyingsystemtype:對映型別;

3.type的方法:

getmethod():返回乙個方法的資訊;

getmethods():返回所有方法的資訊。

這裡其實就是:

然後就能利用type做一些反射的操作了,我們這裡只是用它得到結構的大小。

下面就是實際的操作使用:

在貼**之前,先學習乙個方法,我們能把字串和位元組陣列很好的轉換了,現在也能把結構體和位元組陣列轉換了,但是字元陣列和字串怎麼轉換呢:

string 轉換成 char

string ss="abcdefg";

char cc=ss.tochararray();

char 轉換成string

string s=new string(cc);

先來看客戶端**:

using system;

using system.collections.generic;

using system.linq;

using system.text;

using system.net;

using system.net.sockets;

using system.threading;

catch(exception ex)

//通過clientsocket接收資料

int receivenumber = clientsocket.receive(buffer);

byte receivebytes = new byte[receivenumber];

//利用array的copy方法,把buffer的有效資料放置到乙個新的位元組陣列

array.copy(buffer, receivebytes, receivenumber);

//建立乙個新的operator類

socketstruct.operator myoper = new socketstruct.operator();

myoper = (socketstruct.operator)(bytesandstruct.bytestostruct(receivebytes, myoper.gettype()));

string id = myoper.id.tostring();

string name = new string(myoper.name);

string password = new string(myoper.password);

console.writeline("結構體收到:" + id + " " + name + " " + password );

//啟動新的執行緒,給server連續傳送資料

thread sendthread = new thread(sendmessage);

//把執行緒設定為前台執行緒,不然main退出了執行緒就會死亡

sendthread.isbackground = false;

sendthread.start(clientsocket);

console.readkey();

}//main

/// /// 啟動新的執行緒,傳送資料

///

///

private static void sendmessage(object clientsocket)

", sendmessage);

}catch (exception ex)

}//for

}//sendmessage()

}//class

}

這裡注意一下,我們的接收資料緩衝區一般都設定的要比實際接收的資料要大,所以會空出一部分。但是在把位元組陣列轉換成結構的時候,要丟棄這些空白,所以按照接收到的位元組的大小,重新new乙個位元組數字,並把有效資料拷貝進去。然後再轉換成結構。

伺服器**:

using system;

using system.collections.generic;

using system.linq;

using system.text;

using system.net;

using system.net.sockets;

using system.threading;

//main()

/// /// 新執行緒:監聽客戶端連線

///

private static void listenclientconnection()

//while

}//listenclientconnection()

/// /// 接收資料訊息

///

/// 監聽socket生成的普通通訊socket

private static void receivemessage(object clientsocket)

訊息", myclientsocket.remoteendpoint.tostring(), encoding.ascii.getstring(buffer, 0, receivenumber));

}catch(exception ex)

}//while

}//receivemessage()

}//class

}

這個程式**的不好之處在於沒有很好的處理好socket的關閉。不過這不是重點。

重點是實現c#中傳送結構體資料。

socket 檔案傳輸 C 傳送端

接收端 c,使用socket傳輸檔案的服務端 主函式也可作為一般服務程式的基本框架。主程式 author hhy time 2020 3 7 basic io include include include structure include include socket include signa...

VC中使用Socket網路檔案傳輸結構

1.socket stream file info格式 typedef struct socket stream file info socket stream file info,psocket stream file info 2.檔案傳送 cfile myfile if myfile.open...

VC中使用Socket網路檔案傳輸結構

1.socket stream file info格式 typedef struct socket stream file info socket stream file info,psocket stream file info 2.檔案傳送 cfile myfile if myfile.open...