|
http://www.hackerschool.org/HS_Boards/zboard.php?AllArticle=true&no=1627 [복사]
서버코드
#include <stdio.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define PORT 9000
#define BSIZE 30
char buffer[BSIZE]="Hello,World!\n";
char rBuffer[BSIZE];
int main(){
int len,n,length;
int c_sock,s_sock;
char *temp;
struct sockaddr_in s_addr,c_addr;
s_sock=socket(PF_INET,SOCK_STREAM,0);
memset(&s_addr,0,sizeof(s_addr));
s_addr.sin_addr.s_addr=htonl(INADDR_ANY);
s_addr.sin_family=AF_INET;
s_addr.sin_port=htons(PORT);
if(bind(s_sock,(struct sockaddr*)&s_addr,sizeof(s_addr))==-1){
printf("Can Not Bind\n");
return -1;
}
if(listen(s_sock,5)==-1){
printf("Listen Fail\n");
return -1;
}
while(1){
len=sizeof(c_addr);
c_sock=accept(s_sock,(struct sockaddr*)&c_addr,&len);
length=0;
temp=rBuffer;
while((n=read(c_sock,temp,1))>0){
if(*temp=='\r') continue;
if(*temp=='\n') break;
if(*temp=='\0') break;
if(length==BSIZE) break;
temp++;
length++;
}
rBuffer[length]='\0';
printf("receive: %s\n",rBuffer);
if(!strcmp(rBuffer,"printf")){
n=strlen(buffer);
write(c_sock,buffer,n);
}
close(c_sock);
}
close(s_sock);
return 0;
}
클라이언트 코드
(require :asdf)
(asdf:operate 'asdf:load-op 'sb-bsd-sockets)
(defparameter @sock-s
(make-instance 'sb-bsd-sockets:inet-socket :type :stream :protocol :tcp))
(defparameter @host
(sb-bsd-sockets:host-ent-address
(sb-bsd-sockets:get-host-by-name "localhost")))
(defparameter @port 9000)
(defparameter @foo nil)
(sb-bsd-sockets:socket-connect @sock-s @host @port)
(sb-bsd-sockets:socket-send @sock-s "printf" 10)
(setf @foo(sb-bsd-sockets:socket-receive @sock-s nil 30))
(sb-bsd-sockets:socket-close @sock-s)
(format t "*result: ~a~%" @foo)
서버코드는 열혈강의 TCP/IP 소켓 프로그래밍에서 나오는 helloserver 코드입니다.
printf라는 명령을 받았을 경우, Hello,World!라는 문자열을 전송해주는 프로그램이고,
이 서버를 사용할수 있도록 sbcl에서 기본적으로 제공하는 sb-bsd-sockets패키지를 사용하는 방법을 테스트해봤습니다.
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
host-ent-address[sb-bsd-sockets] host-end-point
지정된 호스트에 대한 접근관련 정보를 반환합니다.
EndPoint를 생성하는데에는 아이피 또는 해당 서버를 나타낼수 있는 문자열을 EndPoint형 객체로 변환하는 함수
get-host-by-name이 사용됩니다.
(make-instance 'sb-bsd-sockets:inet-socket :type :stream :protocol :tcp))
소켓을 사용하기 위해서는 sb-bsd-sockets패키지 내부에 정의되어 있는 inet-socket 클래스를 인스턴스 할 필요가 있습니다.
위 코드에서는 tcp 소켓 인스턴스를 생성하고 있습니다.
socket-connect[sb-bsd-sockets] socket host port
위에서 생성된 소켓, 호스트정보,포트번호로 실제로 서버에 접속하는 동작을 수행합니다.
socket-send[sb-bsd-sockets] socket buffer length
buffer의 내용을 소켓을 통해 전송합니다.
sock-receive[sb-bsd-sockets] socket buffer length
socket을 통해 전송되어온 데이터를 반환합니다.
이 함수에서는 buffer 또는 length중 하나만 지정해 주면 되는데,
그 이유는 length가 지정될 경우 buffer 지정은 무시되고, 지정된 크기 만큼의 새로운 버퍼를 만들어 함수 종료후
수신 결과를 반환값으로서 던져주게 됩니다.
만약, buffer를 지정해주고 length를 지정해 주지 않았을 경우에는 buffer가 차지하고 있는 영역위에 수신 데이터를
덮어쓰게 됩니다.
대부분 이러한 처리는 원치 않기 때문에 buffer 영역을 비워두고, length값을 지정하는 형태로 사용됩니다.
sock-close[sb-bsd-sockets] socket
열려 있는 소켓을 닫습니다.
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
완벽한 네트워크 프로그램이 되기 위해서는 클라이언트 코드에도 타임아웃 처리등이 들어가야 하지만,
이 예제는 네트워크 접속을 위한 최소한의 함수의 사용예를 보여주기 위한갓이니 넘어가도록 하겠습니다. |
Hit : 7927 Date : 2010/12/27 10:36
|