p.130~131 op_client.c 부분에서 막혀서 이렇게 글을 씁니다.
학교 서버 리눅스 환경에서 이 소스를 돌려보았습니다.. 그런데..
클라이언트 쪽에서 연결도 됐고, Operand conunt 까지 입력이 되는데
Operand 1 부터 입력을 하면 버스 오류 (core dumped)라는 게 뜨네요..
아무리 찾아봐도 잘 모르겠어서 올립니다.. ㅠㅠ
아무래도 39행인 scanf("%d", (int*)&opmsg[i*OPSZ+1]); 에서 오류가 나는 것 같은데요.
왜 그럴까요 ? ㅠㅠ
미심적어서 소스를 scanf("%d", (int*)&opmsg[i*OPSZ+4]);
이렇게 고쳐보면, 그 뒤 값들은 받아지긴 하지만, 전체적인 로직과, 구현 목적(char 문자에 계산할만큼 숫자를 담아라)이
달라지기에...
34라인의 opmsg[0] = (char)opnd_cnt; 여기서 char형인 1바이트만큼만 기록되야 맞는게 아닌가요?
인터넷에서 대략 찾아보니 메모리가 덤프되는게.. 뭐 겹쳐써지고.. 이런 말도 있고..... ㅠㅠ
알려주세요!!!!!! ㅠㅠㅠㅠㅠ
A.
안녕하세요 해결하지 못해 답변이라 하긴 뭐하지만...
빅엔디안 시스템이 원래 이런 것인지는 잘
모르겠습니다.
op_client.c에서,
문제가 발생하는 부분만 요약했습니다.
1 #include
<stdio.h>
2 #include <string.h>
3
4 #define BUFMAX 9
5
6
7 int main(void){
8 int i;
9
char buf[BUFMAX];
10
11 memset(buf, 0, BUFMAX);
12
scanf("%d", (int
*)&buf[1]);
13
14 for(i=0; i<BUFMAX;
i++)
15 printf("buf[%d]=%0x , %p\n",i, buf[i],
&buf[i]);
16
17 return 0;
18
19
}
12번 줄이 문제가 되는 부분인데,
리틀엔디안 시스템의 리눅스에서는 (int *)&buf[숫자]의
숫자 부분을
범위 내에서 마음대로 줄 수가 있었습니다. 원하는 대로 포인터가 갑니다.
그러나, 솔라리스만 이런 것인지
빅엔디안 시스템이 다 이런 것인지는 모르겠지만,
솔라리스 빅엔디안 시스템에서는 반드시 (int *)&buf[숫자]부분의 숫자가 0,
4, 8 이런 식으로
int의 크기에 맞춰서 써줘야 했고, 중간 숫자 1, 2, 3, 5, 6, 7 같은 숫자를 넣는다면
반드시
Core Dump가 일어났습니다.
** 숫자를 0을 주었을 때...
$./a.out
9
buf[0]=0 ,
ffbff9a8
buf[1]=0 , ffbff9a9
buf[2]=0 , ffbff9aa
buf[3]=9 , ffbff9ab
<-- 하위 바이트의 값을 높은 번지 주소에 저장.
buf[4]=0 , ffbff9ac
buf[5]=0 ,
ffbff9ad
buf[6]=0 , ffbff9ae
buf[7]=0 , ffbff9af
buf[8]=0 ,
ffbff9b0
$
** 숫자를 1을 주었을 때...
$./a.out
3
Bus error (core
dumped)
$
*** 리틀엔디안 시스템의 리눅스에서 숫자 1주고 실행했을 때
$
./a.out
3
buf[0]=0 , 0xbfb10b83
buf[1]=3 , 0xbfb10b84
<--- buf의 1번 주소에 바로 들어갑니다.
buf[2]=0 , 0xbfb10b85 하위 바이트의 값을 낮은 번지
주소에 저장.
buf[3]=0 , 0xbfb10b86
buf[4]=0 , 0xbfb10b87
buf[5]=0 ,
0xbfb10b88
buf[6]=0 , 0xbfb10b89
buf[7]=0 , 0xbfb10b8a
buf[8]=0 ,
0xbfb10b8b
$
솔라리스 빅엔디안 시스템에서
op_client.c, op_server.c의 소스를 그대로
쓸 수 없는 것은
맞는 것 같습니다.
A2.
그냥 되도록 바꿨습니다.
서버 프로그램 쪽에서는 바꿀 코드가
int형으로 선언된 opnd_cnt를
char형으로
바꿔주고,
클라이언트 프로그램 쪽에서는
typedef union charInt{
char intByte[4];
int cInt;
}UsrInt;
위와 같이 scanf()를 통해 받을
정보를
임시저장할 공용체 형을 정의하고 후에 선언한 뒤,
이것을 사용해서 클라이언트에서
피 연산자 값을 입력 받는 부분을
아래와 같이 고쳐서
for(i=0; i<opnd_cnt;
i++)
{
printf("Operand %d: ", i+1);
scanf("%d", &usrInt.cInt);
opmsg[i*OPSZ+1]=usrInt.intByte[0];
opmsg[i*OPSZ+2]=usrInt.intByte[1];
opmsg[i*OPSZ+3]=usrInt.intByte[2];
opmsg[i*OPSZ+4]=usrInt.intByte[3];
}
opmsg[]에 수동으로 값을 맞춰
넣어주니..
솔라리스에서도 잘되네요..
출처: http://cafe.naver.com/cstudyjava.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=20401&
초보01님의 답변^^ 친절한 답변 감사드립니다 - 소켓 공부ing...
'TCP/IP 소켓Prog > tcp/ip 함수' 카테고리의 다른 글
[tcp/ip] 도메인 이름을 이용해서 IP 주소 얻어오기 / IP주소를 이용해 도메인 정보 얻어오기 (0) | 2011.07.29 |
---|---|
[C표준함수] memset() 함수 (0) | 2011.07.25 |