사물인터넷_0523

allzeroyou·2022년 5월 23일

사물인터넷

목록 보기
7/7

학습목표

ip주소, port번호를 바꾸는데 함수의 arg형태로 바꿀것
옆 친구와 소통을 위한 프로토콜 형태(헤더정보로, 구조체로 보냄)

AF_INET: Ipv4
SOCK_STREAM: TCP(<=> SOCK_DGRAM: UDP)
TCP 헤더에 ACK 등을 날려야 하지만, UDP는 필요가 없어서 헤더 정보가 좀 다름

stdio.h
=> standard in out : 표준 입출력

입출력이 많이 존재한다.
패킷 input/output, file 입출력, 블루투스 입출력, 데베 입출력이 있음

터미널 환경(화면)은 stdio를 사용

std(standard): 화면에 관한 이야기임

printf, scanf가 stdio.h에 존재함

표준 입출력: 표준 입력(키보드 입력), 표준 출력(화면에 보여줌), 표준 에러
ssh 접속해서 보는 거 => 표준 출력
키보드로 치는 모든 것은 표준 입력임

표준에러는 에러 전용 터미널에 보임
fd는 열때마다 생성이 된다,.
fd는 번호 0(입력),1(출력),2(에러)가 정해져 있음

이때, 표준 에러를 볼 수 있는 코드를 짜야 함
표준 에러를 보는 툴이 있는데, 프로그램 설치 전에는 보이지 않음

에러 메세지가 복잡하게 보이면 예쁘지 않음
에러 메시지를 보고 싶을 때만 사용

굳이 귀찮으니 perror를 쓰면 에러를 보는 창을 열어야 하니 printf 로 변경했음

소켓만들때
fd: file descriptor 사용

파일 디스크립터(File Descriptor)란 리눅스 혹은 유닉스 계열의 시스템에서 프로세스(process)가 파일(file)을 다룰 때 사용하는 개념으로, 프로세스에서 특정 파일에 접근할 때 사용하는 추상적인 값이다. 파일 디스크럽터는 일반적으로 0이 아닌 정수값을 갖는다.

이유?

etc은 시스템 설정 파일들이 속함
home: user 설정파일
mnt: 외장하드, 하드드라이브
root: super user의 디렉토리
proc: 현재 프로세스를 본다
bin: 실행 파일들이 binary 디렉토리에 속함
하얀색 화살표 => 심볼릭 링크(바로가기)
sbin: super user의 bin(관리자 계정에서 실행의 여부)
ls은 bin에 속함
sbin을 실행하기 위해서는 sudo를 앞에 붙여줘야 함

dev(device): 현재 리눅스에 잡혀있는 활성화된 디바이스들임
ls로 보인다는 것은 file임
윈도우와 체계가 다름
전부 파일로 처리를 하기 때문에..

tty는 터미널 관련 터미널임
tty0가 실제로 서버에 접근해 서버의 콘솔을 열어 제어하는 것

cd proc
ls

라즈베리 파이에 올라가 있는 프로세스 테이블에 나와있는 모든 프로세스 들이다.
현재 proc에 있는 파일에다가 os가 업데이트를 해준다.

파일로 되어있다고 해서 뭔가 실제로 사이즈를 차지하고 써져있는 물리적인 파일이 아닌, 각각의 시스템에서 처리하는 정보들을 파일로 처리함(실제로 하드에 저장되어 잇는건 아님)

쿼드코어라 각 코어마다 현재 어떤 상태인지 나와있음(cat cpuinfo, vi cpuinfo 등으로 확인 가능. 읽기만 가능)

memset

해당 주소로 가서 지정한 값으로 얼만큼 채워라
0x00로 채우겠다는 건 그 곳을 초기화 하겠다 라는 뜻

주소:배열명, 함수명
나머지는 값임
따라서 구조체도 값임

배열을 초기화 하고 싶다면 굳이 주소 값을 써주지 않아도 ok

접속에 필요한 정보들이 담겨 있음

addr이라는 구조체 안에 sin_addr이라는 구조체 안에 정보가 있음
loop back ip: 127.0.0.1
ip config를 써서 알 수 있는데, loop back ip를 사용하면 이건 무조건 내 컴퓨터의 ip가 됨

옆 친구에게 패킷을 날리고 싶다면, inet_addr의 매개변수에 옆 친구의 ip를 채워주면 됨
이때 inet_addr은 우리가 입력한 문자열을 진짜 ip체계(32bit)로 변경해준다.
<입력할 것>
ipv4/v6?
ip주소
포트번호

만약 옆 친구로 접속하고 싶다면 옆 친구의 열려진 port로 접근해야

htons: host order => network order로 변경
s는 short타입임
l는 long타입임

ntoh: 받았을 경우

이걸 해야 값이 제대로 출력됨

서버 => ctrl+c누르고 다시 접속하니 bind 에러남

ctrl+c로 강제종료를 하니 내 프로세스를 kill함
시스템에서는 kill했는지 알 수 없으니, 이미 예약되어 있다고 알려줌.

시스템도 현재 프로세스가 어떤게 죽어있는지 모니터링을 하는데, 너무 자주 하지 않고 중간중간 체크를 함

bind 에러가 나니까, port 번호를 바꾼 후 compile하고 실행함

=> 실행할 때 포트를 입력해주면 될듯!

argument를 전달해주는 방식으로 전달해보자

실행할 때 값을 줘보자!

int main(void) => 프로그램을 실행할 때 매개변수를 주지 않음
사용자로부터 입력을 받는 방법을 해보자

./server(한칸 띄우기)"포트번호"
main함수로 arg가 몇개든 간에 끌고 올 수 있는 방법??

실행명 arg arg arg ...

int main(int argc, char*argv[] )
argc(count): 단어 수(example에서는 4개)
argv(value): 배열/ argv[0], argv[1], argv[2], argv[3]임

char*argv[]: 하나하나가 포인터 집합임

or
int main(int argc, char**argv )
이중포인터 -> 2차원 배열을 사용

ex. ls -al ./aa

:현재 aa라는 디렉토리 안에 있는 걸 자세히 보여줘
단어수는 3개, argc: 3
argv[0]는 문자열 배열이다.

  1. client에서 포트를 입력받아서 server에서 실행하는 걸로 바꿔보기
    *argv[]는 문자열임
    문자열을 숫자로 바꿔줘야
    atol 이용
  2. 잘 되면 ip도 argument로 받기
    ip는 client에서만 받으면 됨
  3. 옆 친구와 채팅해보기

메시지를 입력할때 띄어쓰기가 있는 문장은 중간에 짤려서 보내는 현상 발생 => gets 함수를 사용하면 해결!
그냥 scanf("%s", msg) 였던 것을 gets(msg)로 변경해주면 된다!
<관련 레퍼런스>
https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=tipsware&logNo=220980599139

bind에러 나면 그때 포트번호 바꿔주면 된다.

완성 코드 : 서버

완성 코드: 클라이언트

led 관련 코드는 아래 주제를 위한 것

구조체 보내기

typedef struct led{
int led_num;
int op; // 1: in, 0: off
}led_t;

main(void)
{
led_t led;
led.led_num=1;
led.op=1;
}

서버에 전달해줘야
배열의 값이 아닌,

구조체의 주소를 전달해주면 됨!
send(~~~&led);

이때 send 함수는 led의 구조체값이 아닌, void형 포인터의 주소값을 전달해줘야!
send(~~ (void*)&led)

클라이언트에서 보내고 서버에서 받은 다음에 해당 되는 값을 변경해줘야

클라이언트 화면으로 led번호와 op(on/off)를 받은 다음에, 서버는 클라이언트에서 전달한 내용만 받음

서버와 클라이언트에서 구조체 파일을 둘다 불러와야하니까 구조체 헤더 파일을 만들자!

profile
모든 건 zero 부터, 차근차근 헛둘헛둘

0개의 댓글