2016-10-28 3 views
0

저는 C 프로그래밍에 비교적 익숙하지 않고 아직 답변을 찾지 못했습니다. 정수, 문자 및 longs를 TCP 연결을 통해 바이트로 올바르게 보내고 받으려고합니다. 저는 이것을 만들었지 만 아직 작동하지 않습니다.C에서 TCP/IP를 통한 바이트 배열 송수신

보낸 사람 :

int a = 12345; 
char b = -1; 
unsigned long c = 12174723939; 
unsigned char array[256]; 


array[0] = (a >> 0) & 0xFF; 
array[1] = (a >> 8) & 0xFF; 
array[2] = (b >> 16) & 0xFF; //Is this correct for -1? 
array[3] = (c >> 24) & 0xFF; 
array[4] = (c >> 32) & 0xFF; 
array[5] = (c >> 40) & 0xFF; 
array[6] = (c >> 48) & 0xFF; 

send(socket, array, sizeof(array),0); //or is &array better? 

수신기 :

int a; 
char b; 
unsigned long c; 
unsigned char array[256]; 

recv(socket, array, sizeof(array),0); 

a |= (array[0] << 0) & 0xFF; 
a |= (array[1] << 8) & 0xFF; 
b |= (array[2] << 16) & 0xFF; 
c |= (array[3] << 24) & 0xFF; 
c |= (array[4] << 32) & 0xFF; 
c |= (array[5] << 40) & 0xFF; 
c |= (array[6] << 48) & 0xFF; 

이 맞습니까? 없어진 물건 있어요? 다른 해결책이 있습니까?

수신 부분은 어떻게 처리됩니까? 나는 크고 작은 엔디안에 대해 읽었습니다 (htonl/htonsntohl/ntosl). 예를 들어이 코드에서 구현하는 방법에 대한 예가 있습니까? 당신이 역순으로

a += array[1]; 
a<<=8; 
a += (array[0]); 

생각하지만 왼쪽 Shift 서명 값을 기준으로 UB 떨어져 있다는 사실을 숙지 수신 측에

+0

동일한 상자에서 서버와 클라이언트를 실행할 때 엔디안 효과는 정의가 아닙니다. – alk

+0

@alk 그러나 미래의 사용을 위해 소프트웨어를 설계하는 것은 항상 좋은 시간을 투자합니다. "동일한 박스"에서 "분산 버전"사이의 단계는 매우 짧습니다. – LPs

+0

@LP : 나는 완전히 동의합니다. 나는 단지 "* 작동하지 않습니다. *"는 endianess와 관련이 없을 수도 있음을 알고 싶었습니다. – alk

답변

0

말한다

6.5.7.4

E1 <의 결과 < E2는 E1 왼쪽 시프트 된 E2 비트 위치입니다. 비워진 비트는 0으로 채워집니다. E1에 부호없는 유형이있는 경우 결과 값은 E1 × 2E2이며 결과 유형에서 표현할 수있는 최대 값보다 하나 더 모듈로 감소합니다. E1에 부호가있는 유형 및 음이 아닌 값이 있고 E1 * 2E2가 결과 유형에서 나타낼 수있는 경우 결과 값은 입니다. 그렇지 않으면 동작이 정의되지 않습니다.

+0

고맙습니다. 그래서 전체 배열의 마지막 바이트에서 시작하고 첫 번째 오른쪽으로 이동해야합니까? – Frechdachs

1

작성한 내용이 올바르지 않습니다.I는이 순서로 포함하는 부호 문자 버퍼 구축들이 의도한다고 가정

  • int 값 12345
  • char 값 -1
  • 을 표현을 포함하는 바이트 표현의 두 최하위 바이트 당신은 작성해야 12174723939

long 값의 표현을 포함한 4 가장 낮은 바이트 :

array[0] = (a >> 0) & 0xFF; // lowest byte 
array[1] = (a >> 8) & 0xFF; // next 
array[2] = b; // cast a char to an unsigned char 
array[3] = (c >> 0) & 0xFF; // lowest byte of c 
array[4] = (c >> 8) & 0xFF; 
array[5] = (c >> 16) & 0xFF; 
array[6] = (c >> 24) & 0xFF; 

그리고 당신은 전체 버퍼하지만 흥미로운 부분 보내지한다 : 7 바이트 :

a = array[0]; // start with an initial value 
a |= array[1] >> 8; 
b = array[2]; // is already a single byte 
c = array[3]; 
c |= array[4] >> 8; 
c |= array[5] >> 16; 
c |= array[6] >> 24; 

참고 : 수신기 부분에서

send(socket, array, 7, 0); 

, 당신은 자신의 바이트의 값을 다시 당신으로 명백히 최하위 바이트를 전송하여 엔디안을 처리합니다. 다른 엔디안을 사용하는 여러 컴퓨터에서 사용할 수 있습니다.

+0

와우. 나는 그것을 최대한 빨리 시험 할 것이다! 미리 감사드립니다! – Frechdachs

+0

나는 그것을 시험해 보았지만 두 가지는 아직 작동하지 않았다. - char를 unsigned char에 캐스팅했다. 이 값을 출력 할 때 255 (-1) 및 254 (-2)입니다. 나는 그것이 지금까지 괜찮다고 생각한다. 하지만 다른 측면에서 나는 항상 그 값을받지 못합니다. 때로는 다른 음수 값을 보낼 때 대신에 양수 값을 얻습니다. 왜 그런지 알아? - 새로운 변수에 배열 값을 저장하는 것은'>>'대신'<<'를 사용하면 더 잘 작동합니다. 임 for-routines와 함께 일하고 어쩌면 내가 계산 문제도 가지고있다. – Frechdachs

+0

@Frechdachs : 0xFF (또는 255)는'(char) -1'의 2의 보수 표현입니다. 다르게'(unsigned char) 255'와'(signed char) -1'는 같은 이진 표현 인'0xFF'를 공유합니다. –