소켓 프로그래밍 part 2~4 TCP/IP
Programming/Networking 2006. 7. 15. 18:46
TCP/IP 소켓 프로그램의 기본적 예제
대략적 구조
Server ------------------------------Pipe-------------------------------------Client
socket 함수 socket 함수
| |
bind 함수 Connect 함수
| |
listen 함수 |
| |
accept 함수 |
| |
read,write read,write
send,recv함수 send,recv함수
| |
소켓닫기 소켓닫기
세부사항
<SERVER>
0> 해더파일을 삽입한다
#include<stdio.h> printf();
#include<stdlib.h> exit();
#include<string.h> memset();
#include<arpa/inet.h> socket();.......
#include<sys/types.h> ''
#include<sys/socket.h> ''
1>sockaddr_in 구조체를 선언한다...
ex>struct sockaddr_in server; (타입케스팅 할땐 struct sockaddr *)
2>struct 구조체 안의 변수에 값들을 채워준다,
bind등의 함수가 이 구조체의 값을 사용한다
sockaddr_in 구조체의 내부 변수들은 다음과 같이 설정해 준다
ex>
memset(&server,0,sizeof(server)); //구조체 할당하기전에 먼저 초기화
server.sin_family=AF_INET; //IP의 성격 설정 대부분 ip4를 사용하므로 이렇게 설정
server.sin_port=htons(atoi(argv[1])); //host->Network (type short)
server.sin_addr.s_addr=htonl(INADDR_ANY); //host -> Network (type long) 일단 그냥 외우자
INADDR_ANY는 현재 자신의 IP주소를 말한다 지금 설명하는 프로그램은 서버이므로 자기 자신의
IP를 저장하고 있어야 한다
3>소켓을 만들어 준다
(listen함수에서 만들어진 큐을 제어하는 소켓이다 클라이언트와 연결되 작업하는그런 소켓이
아님을 명심하자)
if((sockid=socket(AF_INET,SOCK_STREAM,0))==-1){
perror("Socket Created ERROR");
exit(1);
}
아래는 man 페이지 수정/추가>
소켓은 지시된 통신 semantics를 지정하는 type 을 갖는다. 현재 정의된 타입은 다음과 같다:
SOCK_DGRAM <UDP>
데이타그램 지원
SOCK_STREAM 레코드 경계를 보호하진 않는다. 스트림 소켓은 모든 데이타가 그것으로 송수신 되기전에 접속 상태이어야한다. <TCP/IP>
에러가 생겼을때 socket함수는 -1을 리턴 한다는걸 알수있다..
아래껏도 대부분 그렇다
4>bind 함수를 만들어 준다,각 주소로 연결하는 함수
if(bind(sockid,(struct sockaddr *)&server,sizeof(server))==-1){
perror("Socket Bind ERROR");
exit(1);
}
bind(소켓 파일디스크립터,sockaddr_in 구조체 주소(꼭 타입 케스팅 할것!), 구조체의 크기);
여기서 소켓 파일 디스크립터란(또는 id?) 그리고 타입케스팅 할때 _in 빼자
5>대기열 생성
if(listen(sockid,5)==-1){
perror("Listen ERROR");
exit(1);
}
간단한 함수...
listen(소켓 id,대기 큐 갯수);
대기열을 왜 만드냐하면... 클라이언트가 한번에 여러개 접속할수 있으니까...
막 일려올때 순서를 정해서 일을 처리하기 위해서*/
6>연결 허용 accept함수
aceept함수는 크기를 줄때 주소로 주어야 한다
또 이함수는 새로운 소켓 id을 반환한다..
추가> 아까 만든 소켓을 대기큐를 제어하는데 쓰이는 소켓
이번에 만들어진 소켓이 정말 데이터를 처리한다*/
faccept=sizeof(client);//주소 때문에 이렇게 함
if((sockid2=accept(sockid,(struct sockaddr *)&client,&faccept))==-1){
perror("Aceept ERROR");
exit(1);
}
accept함수의 리턴값이 바로 accept함수가 만들어준 새로운 소켓의 파일 디스크립터이다
7>나머지는 파일 입출력과 같다..
이 파일 디스크립터로 네트워크의 호스트에 연결된것이다 이 리턴된 파일 디스크립터 로 일반 표준 입출력
처럼 사용하면 된다(파이프를 연상하면 그나마 비슷할까)*/
while(1)
{
read(sockid2,buf,100);
printf("%s",buf);
write(sockid2,buf,100);
}
8>소켓을 닫는것을 일반 파일과 같게 적용되기도 한다
close(sockid2);
절대 강조! (나에게 쓰는 메세지)
리턴값 처리해줘야 하는 함수는 socket(),accept() 함수 밖에 없다!!
(이상한거 리턴받아 쓰지 말자!!!!!!!!)
<Client>
(여기서 숫자는 서버의 단계 숫자)
일단 0~3까지의 순서는 SERVER와 같다
4~6의 과정은 쓰지 않는다
그러므로 생략 중간에 Connect함수쓰는거 빼면
7~8번째도 같다
이번엔 귀찮으니깐 Connect함수만 쓰도록 한다
if(connect(sockid,(struct sockaddr *)&server,sizeof(server))==-1){
perror("Connect ERROR");
exit(1);
}
뭐.. 설명이 필어 없을듯 하다 인자는 Bind함수랑 비슷하다(같은건가?)
서버와 연결을 할때 쓰는 함수다
7>
단 read,write쓸때
read 하면 클라이언트에서 받을거고
write하면 클라이언트에서 메세지를 보낸다
라는 약간의 차이가 있다
파일 디스크립터(클라이언트 에게 보넬 입출력 fd) 는 소켓을 생성한 파일 디스크립터에다가
read,write하면 된다
8> 번에 대해서는 뭐 당연하다고 생각하는데로 생각하면 된다
서버와 연결을 할때 쓰는 함수다 자세한건 Manpage~
대략적 구조
Server ------------------------------Pipe-------------------------------------Client
socket 함수 socket 함수
| |
bind 함수 Connect 함수
| |
listen 함수 |
| |
accept 함수 |
| |
read,write read,write
send,recv함수 send,recv함수
| |
소켓닫기 소켓닫기
세부사항
<SERVER>
0> 해더파일을 삽입한다
#include<stdio.h> printf();
#include<stdlib.h> exit();
#include<string.h> memset();
#include<arpa/inet.h> socket();.......
#include<sys/types.h> ''
#include<sys/socket.h> ''
1>sockaddr_in 구조체를 선언한다...
ex>struct sockaddr_in server; (타입케스팅 할땐 struct sockaddr *)
2>struct 구조체 안의 변수에 값들을 채워준다,
bind등의 함수가 이 구조체의 값을 사용한다
sockaddr_in 구조체의 내부 변수들은 다음과 같이 설정해 준다
ex>
memset(&server,0,sizeof(server)); //구조체 할당하기전에 먼저 초기화
server.sin_family=AF_INET; //IP의 성격 설정 대부분 ip4를 사용하므로 이렇게 설정
server.sin_port=htons(atoi(argv[1])); //host->Network (type short)
server.sin_addr.s_addr=htonl(INADDR_ANY); //host -> Network (type long) 일단 그냥 외우자
INADDR_ANY는 현재 자신의 IP주소를 말한다 지금 설명하는 프로그램은 서버이므로 자기 자신의
IP를 저장하고 있어야 한다
3>소켓을 만들어 준다
(listen함수에서 만들어진 큐을 제어하는 소켓이다 클라이언트와 연결되 작업하는그런 소켓이
아님을 명심하자)
if((sockid=socket(AF_INET,SOCK_STREAM,0))==-1){
perror("Socket Created ERROR");
exit(1);
}
아래는 man 페이지 수정/추가>
소켓은 지시된 통신 semantics를 지정하는 type 을 갖는다. 현재 정의된 타입은 다음과 같다:
SOCK_DGRAM <UDP>
데이타그램 지원
SOCK_STREAM 레코드 경계를 보호하진 않는다. 스트림 소켓은 모든 데이타가 그것으로 송수신 되기전에 접속 상태이어야한다. <TCP/IP>
에러가 생겼을때 socket함수는 -1을 리턴 한다는걸 알수있다..
아래껏도 대부분 그렇다
4>bind 함수를 만들어 준다,각 주소로 연결하는 함수
if(bind(sockid,(struct sockaddr *)&server,sizeof(server))==-1){
perror("Socket Bind ERROR");
exit(1);
}
bind(소켓 파일디스크립터,sockaddr_in 구조체 주소(꼭 타입 케스팅 할것!), 구조체의 크기);
여기서 소켓 파일 디스크립터란(또는 id?) 그리고 타입케스팅 할때 _in 빼자
5>대기열 생성
if(listen(sockid,5)==-1){
perror("Listen ERROR");
exit(1);
}
간단한 함수...
listen(소켓 id,대기 큐 갯수);
대기열을 왜 만드냐하면... 클라이언트가 한번에 여러개 접속할수 있으니까...
막 일려올때 순서를 정해서 일을 처리하기 위해서*/
6>연결 허용 accept함수
aceept함수는 크기를 줄때 주소로 주어야 한다
또 이함수는 새로운 소켓 id을 반환한다..
추가> 아까 만든 소켓을 대기큐를 제어하는데 쓰이는 소켓
이번에 만들어진 소켓이 정말 데이터를 처리한다*/
faccept=sizeof(client);//주소 때문에 이렇게 함
if((sockid2=accept(sockid,(struct sockaddr *)&client,&faccept))==-1){
perror("Aceept ERROR");
exit(1);
}
accept함수의 리턴값이 바로 accept함수가 만들어준 새로운 소켓의 파일 디스크립터이다
7>나머지는 파일 입출력과 같다..
이 파일 디스크립터로 네트워크의 호스트에 연결된것이다 이 리턴된 파일 디스크립터 로 일반 표준 입출력
처럼 사용하면 된다(파이프를 연상하면 그나마 비슷할까)*/
while(1)
{
read(sockid2,buf,100);
printf("%s",buf);
write(sockid2,buf,100);
}
8>소켓을 닫는것을 일반 파일과 같게 적용되기도 한다
close(sockid2);
절대 강조! (나에게 쓰는 메세지)
리턴값 처리해줘야 하는 함수는 socket(),accept() 함수 밖에 없다!!
(이상한거 리턴받아 쓰지 말자!!!!!!!!)
<Client>
(여기서 숫자는 서버의 단계 숫자)
일단 0~3까지의 순서는 SERVER와 같다
4~6의 과정은 쓰지 않는다
그러므로 생략 중간에 Connect함수쓰는거 빼면
7~8번째도 같다
이번엔 귀찮으니깐 Connect함수만 쓰도록 한다
if(connect(sockid,(struct sockaddr *)&server,sizeof(server))==-1){
perror("Connect ERROR");
exit(1);
}
뭐.. 설명이 필어 없을듯 하다 인자는 Bind함수랑 비슷하다(같은건가?)
서버와 연결을 할때 쓰는 함수다
7>
단 read,write쓸때
read 하면 클라이언트에서 받을거고
write하면 클라이언트에서 메세지를 보낸다
라는 약간의 차이가 있다
파일 디스크립터(클라이언트 에게 보넬 입출력 fd) 는 소켓을 생성한 파일 디스크립터에다가
read,write하면 된다
8> 번에 대해서는 뭐 당연하다고 생각하는데로 생각하면 된다
서버와 연결을 할때 쓰는 함수다 자세한건 Manpage~
'Programming > Networking' 카테고리의 다른 글
gethostbyname 의 세그멘테이션 오류 (2) | 2008.02.28 |
---|---|
소켓shutdown..DomainName<->IP (0) | 2006.07.18 |
TCP/IP 추가 and UDP /IP (0) | 2006.07.18 |
열혈강의 TCP/Ip Socket Programming --Part 1 (1) | 2006.07.06 |