2017-11-07 3 views
0

Ich habe versucht, das ganze Google zu suchen, um richtig zu fragen. Aber ich habe immer noch nicht verstanden, was vor sich geht. Hier das Problem: Ich habe einen TCP-Client von C-Sprache geschrieben. Es ist einfach, einen binären Stream an einen TCP-Server von Netty zu senden. Erstens, machen Sie es einfach, tcp Server nur die gesamten Daten von Server zu Client echo. Aber es ist komisch, dass Bytebuf "writeShort" in buff verwendet, der Client wechselt den Edian von BIG-endian nach Small-edian. So konvertieren Sie 0x007b in 0x7b00. Ich weiß nicht, ob es ein Fehler ist. nach dem Code: c TCP-Client:Netty Bytebuf writeShort kann nicht korrekt an C-Client senden

#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 Server von netty:

proto:

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; 
     } 

    } 

decode:

public class ProtoDecoder erstreckt 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; 
    } 
} 

}

kodieren:

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))); 

    } 
} 

vielen Dank!

Antwort

0

Es ist möglich, dass Ihr Protokoll und c impl erwartet LITTLE_ENDIAN. Wenn dies der Fall ist:

byteBuf.writeShortLE(...) 
+0

Korrigieren, nachdem ich Frage gestellt habe und ich dieses Problem behoben habe. Der Kunde ist Little-Endian. Danke trotzdem. –

+0

Bitte upvote dann;) –

Verwandte Themen