블로그 이미지
송시혁

calendar

1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30

Notice

Tag

Recent Post

Recent Comment

Recent Trackback

Archive

2013. 6. 20. 16:13 네트워크/vmware 실습

나머지 위는 저번시간에 배운것과 동일하다. 다시 한 번 select()함수를 살펴본다.



FD_ZERO, FD_SET부분은 위에 주석문을 참고하여 본다.

두 번째 FD_SET부분에서 소켓에 번호를 감지한다.

그리고 SELECT()함수를 호출하여 소켓에 클라이언트로부터 어떤 정보가 들어왔는지, 혹은 이벤트가  발생하지 않았는지를 인식한다.

(이벤트 발생 감지 부분)


SELECT()함수의 인자로 SOCK+1이 되어 있는 것을 알 수 있다. 기본적으로 0,1,2는 키보드, 모니터, 에러이고 그 다음부터 3번부터 보통 SOCK(소켓)의 번호가 부여된다. 첫 번째 인자의 1을 한것은 SELECT함수 설명부분의 +1을 해야한다고

나와있다. 즉, 처음 생성된 소켓의 번호는 4번이 된다. 


FD_ISSET()함수에서 키보드로부터 받은 데이터를 확인하여 정상처리가 된다면, 1을 반환한다. 따라거 조건문인 IF문을 

만족한다면, 아래에 READ()함수나 WRITE()실행된다.


나머지는 위의 주석 설명을 본다.


-------------------------------------------서버 분석-------------------------------------------------




iMaxSock= 소켓번호 +1 그이유는 아래에 select()함수의 첫 번째 인자를 위해서 미리 1을 더한 것이다. 이렇게 굳이 변수로 사용한 이유는

클라이언트가 1개가 아닌, 2,3개 이상의 클라이언트가 접속하기 때문에 소켓의 번호가 변하게 된다. 처음 소켓부터 4,5,6,7...이런식으로 변하기

때문에 변수를 사용했다.


FD_SET부분은 생략. 

----------------------------------------------------------------------------------------------------


바로밑에 for문

처음 소켓을 생성시 uIuser는 0이다 그래서 실행되지 않는다.

바로 select()함수가 기다리고 있다. select()함수에서 클라이언트의 전송하고 있는 정보를 기다린다. 아무런 정보가 없으면, 기다린다.

다섯 번째 인자는 struct timival *timeout 구조체 포인터형의 인자, 보통 0으로 하고 , 무한대기 상태가 된다. 단, 클라이언트로부터 데이터가 소켓으로 왔는지 확인이 된다면, 이 프로그램은 select()함수에서 기다리지 않고 아래로 프로그램이 실행된다.

아래 ,if문은 에러처리부분

그리고 아래 if문에서 FD_ISSET()함수에서 소켓에 데이터가 클라이언트로부터 전송이 되었는지 확인되면, 1을 반환하여 

아래 소스를 실행하게 된다.





accept()함수는 소켓번호를 실제로 넣는 부분. 이것을 tempsock에 넣는다.





실행결과












posted by 송시혁
2013. 6. 19. 15:52 네트워크/vmware 실습

서버가 1이고 2가 클라이언트

클라이언트 1이 어떤 메시지를 보내면, 서버가 그것을 받아서 다시 클라이언트0번로 보낸다. 마찬가지로 클라이언트1번으로 메시지를 보내도 서버가 메시지를 받아서 클라이언트0번으로 전송한다.



아래그림은 서버의 그림




클라이언트 0번에서의 화면




클라이언트 1번에서의 화면.



변경된 추가된 변수


int clntSock[MAXUSER];= 클라이언트 소켓을 배열로 만든다. MAXUSER는 2로 define 되어있다.

int tempSock =

int iCnt, iCnt2는 나중에 반복문인 for문을 위해서 사용된 변수



--------------------------------------------소스 분석------------------------------------------------


iMaxSock= servSock+1; //가장 소케번호, select() 함수에 첫 번째 인자로 사용하기 위하여 소켓번호+1로 지정.

기존의 fd_set설정 부분을 반복문 안에 집어넣었다.

두 번째 FD_SET부분에 서버소켓을 첫 번째 인자로 넣는다.





반복뭄이 for문에서 uIuser는 접속자 수를 의미한다. 처음에는 0이므로 for문을 실행하지 않고 select()함수로 가게 된다.

fd_isset()함수에서 1이 반환하게 되면, tempSock에 클라이언트를 받을 때까지 기자리는 accpet()함수를 받는다.


아래 if문은 에러처리 부분.




--------------------------------------------소스 분석 계속--------------------------------------------



 배열로 선언된 clntSock[uIuser]=tempSock; tempSock()에서 넣어서 

후에 증감시킨다. 처음에는 tempSock이 0이므로 증감되어 1이 화면에 출력된다.

접속자 확인 부분이다. 클라이언트가 접속하면, 위에 for문 코드에 의해 화면에 접속자 수가 출력된다.


else if()

read()함수로 키보드로 읽어들여서 다음, for문이 실행되고, 클라이언트[0]자리에 키보드로부터 입력받은 데이터를 각 클라이언트에 보내게 된다.(클라이언트, 접속자 수가 1명인 경우)




그리고 다시 반복문에 의해 while문으로 올라간다.



이번에는 for문이 실행된다. uIuser가 1이므로 0보다 크다. for문을 실행한다.

FD_SET()함수에서 클라이언트[0]자리에 1로 넣는다.

그리고 if문을 실행한다. iMaxSock는 2로 정의 되어 있으므로 2<=clntSock[iCnt2-1]이 된다.

조건을 만족한다면, iMaxSock에 



그리고 아래에 printf문에 iCnt-1을 한 이유는 iCnt가 지금 1이므로 -1을 하면 배열번호가 0이 되어 clntSock[0]이 출력된다.


















posted by 송시혁
2013. 6. 18. 09:58 네트워크/vmware 실습







fd_set= 자료형, 구조체

FD_ZERO=   전부 0으로 채우는 함수, 인자로 fd_set형 변수의 주소를 인자로 넣는다.

FD_SET=      한 바이트씩 1로 채우는 함수

FD_ISSET= 특정자리에 한 바이트씩 1인지 0인지 확인하는 함수

FD_CLR= 한 바이트(128)을 0으로 채우는 함수




client 부분.

FD_SET=      한 바이트씩 1로 채우는 함수로서 첫 번째 인자 0은 fd_status의 첫 번째 비트부분이다.

첫 번째 부분에 두 번째 인자인 fd_status의 주소를 넣으며, 0에 해당한는 비트의 1을 넣는다.

그리고 아래에 FD_SET()함수에 첫 번째 인자의  소켓번호를 넣는다.



select()함수

첫 번째 인자인 n은 전체 128비트중에서 검색하는 대상을 몇개로 할 것인지 지정하는 것. 여기서는 1번만 검색.

100을 입력하면, 100번을 검색하고, 128을 넣으면, 전체 검색을 한다. 당연히 음수나 0으로하면, 검색이 안된다.

에러 메시지를 출력한다.


두 번째, 세 번째 인자는 readfds/writefds이다. 당연히 readfds는 fd_set형 구조체 변수의 데이터를 읽을 수 있는지 확인하는것, 세 번째는 반대로 데이터를 전송하거나, 저장할 수 있는지 여부를 확인한다.


네 번째 예외처리부분이다.(나중에 설명, 배우지 않음)(

다섯 번째 시간설정, 보통 0으로 한다.마찬가지로 배우지 않아 나중에 설명예정.


FD_ISSET()함수에서 0번자리에 1이 들어가있는지 확인하고 1이 맞으면, if문 조건을 만족하여

read()함수와 write()함수를 호출한다.


read()함수에서 키보드를 입력받아 버퍼에 저장한다.

write()함수에서 sock으로 버퍼에 있는 것을 넣어 보낸다.


else if문에서 다시 select()함수를 넣는다.

그리고 서버에서 전송한 데이터를 read함수로 읽는다.

그리고 아래에 write()함수에서 버퍼에 있는 데이터를 화면에 출력한다. iRet-1은

'\n'을 출력치 않기 위해서??? 



server부분


위에 if문 조건까지는 동일하다.

read()함수에서 클라이언트에서 받은 데이터를 읽는다.

그리고 그것을 화면에 출력한다. write()함수부분, 그리고 마찬가지로 else if문에 의해

read()함수로 키보드로 입력받아  write()함수를 써서 클라이언트로 전송한다.이렇게 같은 포트에

쌍방향 채팅이 가능해진다.


다음은 실행결과


서버에서의 화면.



클라이언트에서의 화면









posted by 송시혁
2013. 6. 17. 14:10 네트워크/vmware 실습



클라이언트

 




 

1. 소켓생성

 

Sock=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

서버와 마찬가지로 stream으로 설정한다. 데이터를 하나씩 확인하면서

받을 때 사용.

 

2.구조체 설정


MEMSET = 메모리 셋팅


1바이트씩 특정한 메모리를 다 채워 넣는다.


MEMSET(&echoServAddr, 0, sizeof(echoServAddr));


주소(첫 번째인자) echoServAddr주소(세 번째 인자크기만큼 0을 채워 넣는다. 0을 넣어서 초기화 하는 부분.

 

echoServAddr.sin_family= AF_INET;

패밀리 설정.

echoServAddr.sin_addr.s_addr= inet_addr(serIP);//서버 ip주소 넣는 부분.

 

echoServAddr.sin_port= htons(9999);// 포트번호 설정. 9999로 설정함.

 

 

3.connect()함수

 


iRet=connect(sock, (struct addr*)&echoServAddr, sizeof(echoServAddr ));

 

1. 첫 번째 인자는 생성한 소켓, 소켓번호,

2. 두 번째 인자는 서버의 주소.

3. 크기

 

클라이언트 Connect함수= 서버의 accept함수.,

 

 


 

Read()함수에서 키보드로부터 입력한 값을 버퍼에서 읽어 들인다.

Write()함수에서 버퍼에 있는 문자를 써서 소켓에 보낸다. 그러면,

서버에서 문자를 받는다.(클라이언트가 데이터를 전송하는 부분)

 

다시 read()함수에서 소켓에 있는(서버가 다시 데이터를 다시 전송한) 버퍼를 읽어들여서,

Printf()함수로 글자를 화면에 띄운다.

 

 

 

실행결과

 

서버에서의 화면(클라이언트에서 보낸 문자가 화면에 찍힌다.)


클라이언트에서의 화면


 

“songsihyuk”이라는 문자를 입력하고 서버에 보낸뒤, 다시 그 문자데이터를

클라이언트가 받아낸다.


이제는 memset()함수를 알아보자


첫 번째 인자는 void *vp. void *를 자료형으로 선언한 이유는 echoServAddr은 구조체, 기타 ...등은 다른 자료형을 가지고 있으므로, 이 모든 자료형을 가르킬 수 있는 void *로 선언한다.


두 번째 인자 uCpad는 1바이트씩 데이터를 가르키므로 unsigned char로 자료형을 선택


*(unsigned char *)vp= uCpad;

vp는 주소이다. 그래서 캐스팅다음, 바로 *를 붙여서 상수로 인식시킨다. 이 부분은 uCpad가 데이터를 넣는부분.


세 번째 인자 uIsize는 전체 데이터의 크기이다. 여기서는 5이므로 전체 길이는 다음과 같다.


 

 

 

 

 




--uIsize; 감소한다.

그리고 vp(uCpad)가 가르키는 곳을 이동해야 하므로 주소인 vp에 1을 더하면 된다.

그러나 역시 1바이트씩 이동하고 void형 포인터이기 때문에 캐스팅이 절대적으로 필요

(unsigned char *)형으로 캐스팅해준다. 그러면, 다음 1바이트 이동한만큼의 다음주소를 가르키게 된다.

이로서 memset()함수는 완성이 된다.


그리고 bzero()함수가 memset()함수를 호출하여 실행한다. 실제로 오늘은 memset()함수만 만들고 이것을 컴파일 하지 않았다.



posted by 송시혁
2013. 6. 14. 09:30 네트워크/vmware 실습



int servSock, clntSock

servSock= 파일번호

int= read/write반환형



struct sockaddr_in echoServAddr = 신구조체 서버 ip주소


struct sockaddr_in echoClntAddr= 신구조체 클라이언트 ip주소


unsigned int clntLen= 클라이언트


unsigned short echoServPort= 포트 번호 변수(나중에 포트번호는 9999로 설정함, 0~1023은 원래 관리자만 지정가능함)


DOS

= donial of service


Protocol Family = PF_INET, Protocol=어떤계열을 쓸건지 인자, Family=계열


AF= 0으로 정의 되어있다.

-r 은 현재에서 아래까지 모두 검색


PF_INET=AF_INET


INTE= 인터넷 사용



아래함수는 소켓을 생성하는 부분이다.


1.소켓생성

servSock = socket(AF_INET, SOCK_STREAM, IPPORT_TCP);

 

아래함수는 소켓을 생성하는 부분이다.


servSock = socket(PF_INET, SOCK_STREAM, IPPORT_TCP)//소켓포트


첫 번째 인자에 PF_INET= 프로토콜 방식 결정.


두 번째 인자에 데이터전송방식을 결정.


DGRAM(data gram )= 무조건 데이터 받거나 전송한다상관없이 실행한다.


STREAM= 데이터를 확인하면서 전송(일반파일).


IPPORT_TCP= STREAM일 때 사용.


IPPORT_UDP= DGRAM,일 때 사용.


MEMSET = 메모리 셋팅


1바이트씩 특정한 메모리를 다 채워넣는다.


MEMSET(&echoServAddr, 0, sizeof(echoServAddr));


주소(첫번째인자)에 echoServAddr주소(세번째 인자) 크기만큼 0을 채워넣는다. 0을 넣어서 초기화 하는 부분.




 


 


 



 

2.구조체 설정.



MEMSET = 메모리 셋팅



1바이트씩 특정한 메모리를 다 채워 넣는다.



MEMSET(&echoServAddr, 0, sizeof(echoServAddr));



주소(첫 번째인자) echoServAddr주소(세 번째 인자크기만큼 0을 채워 넣는다. 0을 넣어서 초기화 하는 부분.



echoServAddr.sin_family= AF_INET;


echoServAddr.sin_addr.s_addr= htonl(INADDR_ANY)//little endian big endian으로 바꾼다.


네트워크에서는 big endian을 채택하여 사용하기 때문에 htonl함수에서 INADDR_ANY를 하면, 데이터가 BIG ENDIAN 형태로 된다.

echoServAddr.sin_port= htons(echoServport);// 포트번호 설정

 

 


3. bind함수


1.첫 번째 인자는 소켓


2.두 번째 인자는 소켓주소, 여기서 중요한 것은 캐스팅이다. 구형 구조체로 인식해야 하므로, (struct sockaddr *) 캐스팅 해야 한다.


3. 크기


bind 함수는 위의 구조체를 설정한 것을 소켓의 넣는 역할을 한다.


그리고 if문에서 종료직전에 반드시 소켓을 닫아준다.


 

4.listen()함수


Listen()함수는 소켓이 동시에 접속 시 대기한다. 여기서는 5라고 설정했기 때문에 5개까지 기다릴 수 있다. 첫 번째 인자에 소켓을 넣고, 뒤에 두 번째 인자에는 숫자를 넣어주면 끝.

 

5.accept()


첫 번째 인자에 servSock = 소켓.


두 번째 인자에는 클라이언트 주소를 넣는다. 마찬가지로 구형구조체형으로 캐스팅한다.


클라이언트 주소는 소켓에 들어오는 클라이언트 정보이다.

세 번째 인자에는 클라이언트 크기


accept()함수는 소켓에 클라이언트가 올 때까지 기다리는 함수.


클라이언트가 올 때까지 잠시 동안 대기하고 있다.= bloking 함수

 


 

Read()함수가 clntsock정보에 들어있는 버퍼를 읽어 들인다.


Write() 클라이언트로부터 전송 받은 데이터를 모니터에 iRet크기(전송 받은 데이터 크기)


만큼 나타낸다. 그리고 다시 입력 받은 데이터를 보내기 위해 두 번째write()함수에서 클라이언트 함수에 보낸다.

 


그리고 반드시 아래와 같이 close()해야 한다. 이것은 나중에 클라이언트도 동일







bind함수

bind(cj
























posted by 송시혁
2013. 6. 12. 15:54 네트워크/vmware 실습



vmware workstation을 실행시키면, 다음과 같은 화면이 뜬다.



원래는 실행하고 나면, 아래와 같은 화면이 뜬다. 여기서 alt + ctrl + F1~6중에서 아무거나 눌러보자.

필자는 F1, F2를 눌렀다.




아래 그림은 F1(아래그림은 이미 소스를 작성하고 저장한 상태에서 불러온 그림.



F2를 누른다. F2에서 다시 F1으로 가고 싶으면, 그냥, alt + F1을 누르면된다.

그러나, 주의 할것은 F1~F6에서 F7로 이동할 때는 단순히 alt + F7을 누르면되지만,

하늘색 이미지의 F7상태에서는 반드시 ctrl키와 같이 눌러야 이동이 된다.

( alt + ctrl + F7)




저위의 초록색 버튼을 누르면, 다음 아래와 같은 화면이 뜬다.


login에 root라고 입력한다.

passwd는 1이다. 그러나 키보드를 눌러도 숫자도 보이지 않고 커서도 움직이지 않는다.

c언어의 getch()라고 생각하면된다. (필자는 굉장히 당황하였다.ㅜㅜ)





최초 화면에서 ls -al 이라고 입력하면 위와 같은 화면이 나타난다. 복잡해 보이닌 자신이 윈도우에 만든 프로그램만 나타내기

위해서는 숨겨진 파일이 나타나지 않는 리스트를 보면 된다. 그것의 명령어는 아래그림에서 보이는 바로 ls -l이다.



위와 같이 뜰것이다. lan은 필자가 이미 만들어 놓은 것. 이것을 만드는 방법은 바로아래 설명한다.




ln -s /mnt/hgfs/One/ lan이라고 치면된다. lan은 그냥 사용자가 아무이름이나 쓰면된다. 제일 앞에는 소문자 'ㅣ'이다.

대문자 'I'와 헷갈려선 아니 아니 아니되요~~~


pwd를 치면, 자신의 현재 위치 디렉토리를 알수 있다.






원래는 자동적으로 lan디렉토리에 설정이 되나, 필자는 수업이 끝나고 한번 프로그램을 끈상태에서 실행하였기 때문에

직접 하위 디렉토리로 이동한다. 하위 디렉토리로 이동하는 방법은 다음과 같다.

"cd \디렉토리명" 이렇게 치면된다. 그래서 lan의 디렉토리로 이동하기 위해서 cd \lan이라고 쳤다.

그러면 lan디렉토리로 이동하였다는 것을 알 수 있다.




자, 그렇다면 자신이 위치한 디렉토리에 폴더를 생성해보자. 다음과 그림과 같이 입력하면, 폴더를 생성할 수 있다.



mkdir을 친 후, 만들고 싶은 폴더명을 써주면, 폴더가 만들어진다. 아래그림은 탐색기를 열어 확인한 모습이다.








다음은 소스 작성법이다. 해당하는 디렉토리에서 소스를 작성하고 싶다면, 일단, 소스의 파일부터 생성해야한다.


vi main1.c를 치면, 다음과 같은 화면이 뜨는 동시에 해당 디렉토리에서 main1.c라는 파일이 생성이 된다. 










그리고 원하는 소스를 작성한다.



작성하고 난뒤 ':'를 눌러서, 확장모드로 만든다음 wq를 눌러서 저장한다.

그리고 컴파일을 하는데 gcc -main1.c -o main1이라고 누르면, 컴파일이 된다.

그 상태에서 main1이락 치면 소스의 관한 결과값이 나온다.

아래 그림은 수업시간에 만든 main.c 파일을 컴파일한 모습이다.






그리고 종료시에는 반드시 wq나 q!(저장하지 않고 종료)를 확장모드에서 입력을 한 다음에 

위에 일시정지 버튼을 누른다. 그리고 가장 초기화면이 될때까지 기다린다.(인내심..)


그리고 메뉴에서 flie- exit를 누르고 종료하면된다.

참고로 한/영키를 변환하기 위해서는 space bar+ shift키를 누르면 된다.


posted by 송시혁
prev 1 2 3 next