① 網路傳輸時可以直接發送一個結構體嗎
在網路通訊過程中往往涉及一些有關聯的參數傳遞,例如數組,結構體之類的。對於結構體其實方法挺簡單,由於結構體對象在內存中分配的空間都是連續的,所以可以將整個結構體直接轉化成字元串發送,到了接收方再將這個字元串還原成結構體就大功告成了。
首先,我們建立一個結構體。
struct UsrData{
char usr_id[16];
char usr_pwd[16];
char usr_nickname[16];
};
當然,這個結構體在發送方與接收方都必須聲明。
接下來創建對象並初始化,然後發送。
UsrData sendUser;
memcpy( sendUser.usr_id, 「100001」, sizeof(「100001」) );
memcpy( sendUser.usr_pwd, 「123456」, sizeof(「123456」) );
memcpy( sendUser.usr_nickname, 「Rock」, sizeof(「Rock」) );
send( m_socket, (char *)&sendUser, sizeof(UsrData), 0 );
這樣發送方就已經將這個mUser對象以字元串的形式發送出去了。
最後在接收方做接收。
char buffer[1024];
UsrData recvUser;
recv( m_socket, buffer, sizeof(buffer), 0 );
memcpy( &recvUser, buffer, sizeof(buffer) );
這樣得到的recvUser對象里的數據與sendUser相同了。具體原因其實很簡單,就是因為結構體對象的內存區域連續,同時每個成員的區塊大小都分配好了,當接收完自己的區塊,其實自己的數據已經接收完成。
② java socket 如何發送一個結構體消息,java中結構體是個什麼概念...
有一個socket 程序,一端是c++寫的socket 服務程序
另一端是Java寫客戶端程序,兩者之間需要通信。
c++/c接收和發送的都是結構體,而Java是直接發送的位元組流或者byte 數組。
解決方法:c++/c socket 在發送結構體的時候其實發送的也是位元組流。因為結構體本身也是內存中的一塊連續數據。問題就變成了如何把結構體手動轉成位元組的問題了
採用類似的報頭:
// packet head
typedef struct tagPacketHead{
long PacketID;
long PacketLen;
}PacketHead;此時套介面的讀寫方式為先讀報頭,在報頭中取出數據負載的長度,然後再讀相應位元組的數據。
包頭後面跟上包體,其中包體的長度,就是上面結構體中的PacketLen,Clinet首先接受包頭,因為包頭是兩邊約定好的,所以可以直接Receive一個定長的消息,也就是這個包頭的長度的消息,從包頭中取得包體的長度後,就可以再次Receive一個包體長度的消息了。那麼Java中如何發送一個結構體呢?下面是解決方法:
使用C/S模式,Client為VC6開發,Server為Java,通過Socket通信。
package org.charry.org;
import java.net.*;
/**
*
* 位元組轉換,參考網路文章
*/
class Packet {
private byte[] buf = null;
/**
* 將int轉為低位元組在前,高位元組在後的byte數組
*/
private static byte[] toLH(int n) {
byte[] b = new byte[4];
b[0] = (byte) (n & 0xff);
b[1] = (byte) (n >> 8 & 0xff);
b[2] = (byte) (n >> 16 & 0xff);
b[3] = (byte) (n >> 24 & 0xff);
return b;
}
/**
* 將float轉為低位元組在前,高位元組在後的byte數組
*/
private static byte[] toLH(float f) {
return toLH(Float.floatToRawIntBits(f));
}
/**
* 構造並轉換
*/
public Packet(int packetID, int packetLen, String packetBody) {
byte[] temp = null;
buf = new byte[packetBody.getBytes().length + 8];
temp = toLH(packetID);
System.array(temp, 0, buf, 0, temp.length);
temp = toLH(packetLen);
System.array(temp, 0, buf, 4, temp.length);
System.array(packetBody.getBytes(), 0, buf, 8, packetBody.length());
}
/**
* 返回要發送的數組
*/
public byte[] getBuf() {
return buf;
}
/**
* 發送測試
*/
public static void main(String[] args) {
try {
String tmp = 「test string!」;
Socket sock = new Socket(」127.0.0.1″, 8888);
sock.getOutputStream().write(
new Packet(123, tmp.length(), tmp).getBuf());
sock.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
如果需要用Java 接收結構體的話只需要將上面過程逆過來即可。
③ c語言udp通信能傳結構體嗎
不能來傳結構源體。
主要是三個方法:
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen)
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen)
④ socket套接字,如何發送一個結構體
1.TCP流式套接字的編程步驟
在使用之前須鏈接庫函數:工程->設置->Link->輸入ws2_32.lib,OK!
SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);//創建套接字(socket)。
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//轉換Unsigned short為網路位元組序的格式
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
客戶端代碼如下:
#include <Winsock2.h>
#include <stdio.h>
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );載入套接字型檔
if ( err != 0 ) {
return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
WSACleanup()( );
return;
}
SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);創建套接字(socket)。
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));向伺服器發出連接請求(connect)。