2017-11-07 6 views
0

私は正しい質問を得るためにGoogle全体を検索しようとしました。しかし、私はまだ何が起こっているのか得ていない。ここに問題があります: 私はC言語で書かれたtcpクライアントを持っています。バイナリストリームをNettyのtcpサーバに送るのは簡単です。まず、単純にすると、tcpサーバはサーバからクライアントへのデータ全体をエコーし​​ます。しかし、Bytebuf "writeShort"をbuffに使うのは変です。クライアントはedianをBIG-endianからSmall-edianに変更します。そのような0x007bを0x7b00に変換します。それがバグかどうかわかりません。 C TCPクライアント:網状のNetty Bytebuf writeShortはCクライアントに正しく送信できません

#include <stdio.h> 
#include <sys/socket.h> 
#include <arpa/inet.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 
#include <netinet/in.h> 


#define HALO_HEADER ("halohalo") 
#define DATA_STILL_LEN (14U) 

typedef struct { 
    unsigned char headerId[8]; 
    short package_len; 
    short opType; 
    short res; 
    unsigned char data[100]; 
} halo_transfer_t; 

void printfHaloStructBuf(char* table, halo_transfer_t *packet) 
{ 
    int i = 0; 
    int dataLen = 0; 
    printf("包头Id: %s\n", packet->headerId); 
    printf("包大小: %d\n", packet->package_len); 
    printf("操作码: %d\n", packet->opType); 
    printf("附加数据实际有效长度: %d\n",packet->package_len - DATA_STILL_LEN); 
    printf("附加数据:\n"); 
    dataLen = packet->package_len - DATA_STILL_LEN; 

    if(dataLen < 0) 
     return; 

    for(i=0; i<dataLen;i++) { 
     if((i!=0)&&(i%16==0)) 
      printf("\n"); 
     printf("0x%x, ", packet->data[i]); 
    } 
    printf("\n"); 
} 

void setUpPackageHeaderId(halo_transfer_t *package) 
{ 
    memcpy(package->headerId, HALO_HEADER ,sizeof(package->headerId)); 
} 

void setUpPackage(uint32_t package_len, uint8_t* data, halo_transfer_t *out) 
{ 
    int i = 0; 

    memset(out, 0, sizeof(halo_transfer_t)); 
    setUpPackageHeaderId(out); //头部 
    out->package_len = package_len; 
    out->opType = 123; 
    out->res = 0; 
    for(int i = 0; i < 100; ++i) { 
     out->data[i] = i; 
    } 
} 

#define BUFFSIZE 1024 
void Die(char *mess) { perror(mess); exit(1); } 
int main(int argc, char *argv[]) { 
    int sock; 
    struct sockaddr_in echoserver; 
    char buffer[BUFFSIZE]; 
    unsigned int echolen; 
    int received = 0; 

    if (argc != 3) { 
     fprintf(stderr, "USAGE: TCPecho <server_ip> <port>\n"); 
     exit(1); 
    } 
    /* Create the TCP socket */ 
    if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { 
     Die("Failed to create socket"); 
    } 


    /* Construct the server sockaddr_in structure */ 
    memset(&echoserver, 0, sizeof(echoserver));  /* Clear struct */ 
    echoserver.sin_family = AF_INET;     /* Internet/IP */ 
    echoserver.sin_addr.s_addr = inet_addr(argv[1]); /* IP address */ 
    echoserver.sin_port = htons(atoi(argv[2]));  /* server port */ 
    /* Establish connection */ 
    if (connect(sock, 
       (struct sockaddr *) &echoserver, 
       sizeof(echoserver)) < 0) { 
     Die("Failed to connect with server"); 
    } 

    halo_transfer_t send_data; 
    memset(&send_data, 0x00, sizeof(halo_transfer_t)); 

    unsigned char data[100] = {'\0'}; 

    /* Send the word to the server */ 
    setUpPackage(114, data, &send_data); 
    printfHaloStructBuf("#####发送数据####\n",&send_data); 
    //send(sock, (char*)&send_data, send_data.package_len, 0); 
    int rc = write(sock, (char*)&send_data, send_data.package_len); 
    if(rc < 0) { 
     perror("Client-write() error"); 
     int temp = 0; 
     int length = sizeof(int); 
     rc = getsockopt(sock, SOL_SOCKET, SO_ERROR, &temp, &length); 
     if(rc == 0) { 
      /* Print out the asynchronously received error. */ 
      perror("SO_ERROR was"); 
     } 
     close(sock); 
     exit(-1); 
    } else { 
     printf("Client-write() is OK\n"); 
     printf("String successfully sent lol!\n"); 
    } 

    /* Receive the word back from the server */ 
    int totalcnt = 0; 
    while(totalcnt < send_data.package_len) { 

     /* Wait for the server to echo the */ 
     /* string by using the read() function. */ 
     /***************************************/ 
     /* Read data from the server. */ 
     rc = read(sock, &buffer[totalcnt], send_data.package_len - totalcnt); 
     printf("Receive from server's count: %d\n", rc); 
     if(rc < 0) { 
      perror("Client-read() error"); 
      close(sock); 
      exit(-1); 
     } else if (rc == 0) { 
      printf("Server program has issued a close()\n"); 
      close(sock); 
      exit(-1); 
     } else 
      totalcnt += rc; 
    } 
    printf("Client-read() is OK\n"); 
    printfHaloStructBuf("Recv from server", (halo_transfer_t*)&buffer); 
    //printf("Echoed data from the server len =%d, cnt = %s\n", strlen(buffer), buffer); 

    fprintf(stdout, "\n"); 
    close(sock); 
    exit(0); 
} 

TCPサーバ:

プロト:

public class Proto implements Serializable{ 
     /** 
     * 
     */ 
     private static final long serialVersionUID = 1L; 
     private byte[] headerId; //8 byte 
     private short package_len;//2 byte 
     private short opType; // 2 byte 
     private short res; 
     private byte[] data; // variable 

     public Proto(byte[] headerId, short package_len, short opType, byte[] data) { 
      this.headerId = headerId; 
      this.package_len = package_len; 
      this.opType = opType; 
      this.res = 0; 
      this.data = data; 
     } 

     public short getPackage_len() { 
      return package_len; 
     } 

     public void setPackage_len(short package_len) { 
      this.package_len = package_len; 
     } 

     public short getOpType() { 
      return opType; 
     } 

     public void setOpType(short opType) { 
      this.opType = opType; 
     } 

     public byte[] getData() { 
      return data; 
     } 

     public void setData(byte[] data) { 
      this.data = data; 
     } 

     public byte[] getHeaderId() { 
      return headerId; 
     } 

     public void setHeaderId(byte[] headerId) { 
      this.headerId = headerId; 
     } 
     @Override 
     public String toString() { 
      String strHeaderId = new String(headerId); 
      //String strData = new String(data); 

      return String.format("[headerId=%s,package_len=%d, opType=%x,content=%s]", 
        strHeaderId, package_len, opType, Utils.bytesToHexString(data)); 
     } 

     public short getRes() { 
      return 0; 
     } 

     public void setRes(short res) { 
      this.res = res; 
     } 

    } 

デコード:

パブリッククラスProtoDecoderがByteToMessageDecoder {

@Override 
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception { 
    // TODO Auto-generated method stub 

    if(in.readableBytes() >= 14) { 

     //System.out.println("1-->Decode is running, in length " + in.readableBytes()); 
     byte[] haloId = new byte[8]; 
     short package_len = 0; 
     in.getBytes(0, haloId); 
     package_len = in.getByte(8); 
     int data_len = package_len - 14; 
     //System.out.println("Decode is running, package len " + in.readableBytes()); 
     short opType = in.getByte(10); 
     short res = in.getByte(12); 
     byte[] data = new byte[data_len]; 
     in.getBytes(14, data); 
     System.out.println(String.format("Decode is running, headerId=%s, package_len=%d, opType=%d, data=%s\n", 
       Utils.bytesToHexString(haloId), package_len, opType, Utils.bytesToHexString(data))); 

     Proto p = new Proto(haloId, package_len, opType, data); 
     out.add(p); 

    } else { 
     return; 
    } 
} 
を拡張コード次

}

エンコード:

public class ProtoEncoder extends MessageToByteEncoder<Proto> { 

    @Override 
    protected void encode(ChannelHandlerContext ctx, Proto msg, ByteBuf out) throws Exception { 
     // TODO Auto-generated method stub 
     if (msg == null) { 
      throw new Exception("The encode message is null"); 
     } 
     //System.out.print("Encode msg: " + msg.toString());; 

     ByteBuf buf = Unpooled.buffer(1024); 
     out.writeBytes(msg.getHeaderId()); 
     out.writeShort(msg.getPackage_len()); 
     out.writeShort(msg.getOpType()); 
     out.writeShort(msg.getRes()); 
     out.writeBytes(msg.getData()); 

     byte[] haloId = new byte[8]; 
     byte[] data = new byte[msg.getPackage_len()]; 

     System.out.println(String.format("haloid = %s, package_len = %d, opType=%d, res = %d, data=%s", out.getBytes(0, haloId) 
       ,out.getByte(8) 
     ,out.getByte(10) , 
     out.getByte(12) 
     ,out.getBytes(14, data))); 

    } 
} 

多くの感謝!

答えて

0

あなたのプロトコルとc implには、LITTLE_ENDIANがある可能性があります。この場合、次のようになります。

byteBuf.writeShortLE(...) 
+0

質問を投稿した後、この問題を修正しました。クライアントはリトルエンディアンです。とにかくありがとう。 –

+0

お願いします;) –

関連する問題