socket이란 client-server 모델로 이 두 종단을 네트워크를 통해 데이터를 주고 받고 하기 위한 것이다.
- server-client는 다음과 같은 흐름을 가지고 있다.
1. socket을 초기화(socket)
2. socket에 ip와 port 설정(bind)
3. 연결 대기(listen)
4. 클라이언트의 접속을 받아들임(accept)
5. 데이터 송수신(recv,send)
6. 연결 종료(close)
1. socket 초기화(socket)
2. server로 접속(connect)
3. 데이터 송수신(send,recv)
4. 연결 종료(close)
server_socket_C
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define PORT 7777
int main(void)
{
int sock, client_sock;
struct sockaddr_in addr,client_addr;
char buffer[1024];
int len, addr_len, recv_len;
if((sock=socket(AF_INET, SOCK_STREAM,0))<0){ // 소켓 초기화 AF_INET==ipv4, SOCK_STREAM==TCP
perror("socket ");
return 1;
}
memset(&addr,0x00,sizeof(addr)); // addr 초기화
addr.sin_family=AF_INET;
addr.sin_addr.s_addr=htonl(INADDR_ANY); //INADDR_ANY==아무 ip라도 받아들임
addr.sin_port = htons(PORT); //network byte
if(bind(sock, (struct sockaddr *)&addr,sizeof(addr))<0){
perror("bind ");
return 1;
}
if(listen(sock, 5)<0){
perror("listen ");
return 1;
}
addr_len=sizeof(client_addr);
printf("waiting for clinet..\n");
while(1){
char end[512]="the\r\n";
buffer[recv_len]='\0';
if((client_sock=accept(sock,(struct sockaddr *)&client_addr,&addr_len))>0){
printf("connected ");
while(1){
if((recv_len=recv(client_sock,buffer,1024,0))<0){
perror("recv ");
break;
}
printf("received data : %s\n",buffer);
send(client_sock,buffer,strlen(buffer),0);
if(!strcmp(end,buffer)){
close(client_sock);
printf("disconnected ");
}
}
}
}
close(sock);
return 0;
}
/* the라는 문자가 넘어올시 소켓 종료 그 전에는 지속적으로 데이터를 받음*/
client_socket_c
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define PORT 7777
int main(void)
{
int sock;
struct sockaddr_in addr;
char buffer[1024];
const char *msg = "hello!! world!!";
int recv_len;
if((sock=socket(AF_INET,SOCK_STREAM,0))<0){ // make socket
perror("socket ");
return 1;
}
//socket setup
memset(&addr,0x00,sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_port=htons(PORT);
if(connect(sock,(struct sockaddr *)&addr, sizeof(addr))<0){
perror("connect ");
return 1;
}
if(send(sock,msg,strlen(msg),0)<0){
perror("send ");
return 1;
}
if((recv_len=recv(sock,buffer,1024,0))<0){
perror("recv ");
return 1;
}
buffer[recv_len]='\0';
printf("received data: %s\n",buffer);
close(sock);
return 0;
} // server의 용도와 아직 다름 한번 데이타를 주면 접속이 끊어짐
여기서 신경써주어야 할 부분은 ip와 포트를 htonl, htons를 이용한다.
그 이유는 쓰지 않을 경우 little endian으로 값이 저장 되기 때문에 네트워크 바이트 순서로 바꾸어 주기 위해서 사용한다.
inet_addr도 같은 이유에서 이다.
*해당 글은 개인 공부를 하기 위한 목적이므로 개인적인 생각과 잘못된 지식이 존재할 수 있습니다.