server
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/socket.h> #include <sys/time.h> #include <sys/select.h> #define BUF_SIZE 100 #define SERVER_IP INADDR_ANY //문제1. IP #define SERVER_PORT "9987" //문제1. 포트번호 struct user { char id[10]; char sock_num; }; struct user aa[10]; void error_handling(char *buf); int main() { int sock_check; int serv_sock, clnt_sock; struct sockaddr_in serv_adr, clnt_adr; struct timeval timeout; fd_set reads, cpy_reads; socklen_t adr_sz; int fd_max, str_len, fd_num, i; char buf[BUF_SIZE]; //문제2. 서버 소켓 프로그램 생성 serv_sock=socket(PF_INET, SOCK_STREAM, 0); //문제2. 서버 소켓 주소 정보 초기화 memset(&serv_adr, 0, sizeof(serv_adr)); serv_adr.sin_family=AF_INET; serv_adr.sin_addr.s_addr=htonl(SERVER_IP); serv_adr.sin_port=htons(atoi(SERVER_PORT)); //문제2. 서버 주소 정보 binding if(bind(serv_sock, (struct sockaddr*) &serv_adr, sizeof(serv_adr))==-1) error_handling("bind() error"); //문제2. listening (클라이언트 접속 대기) if(listen(serv_sock, 5)==-1) error_handling("listen() error"); printf("server socket listening...\n"); FD_ZERO(&reads); FD_SET(serv_sock, &reads); fd_max=serv_sock; while(1) { cpy_reads=reads; timeout.tv_sec=5; timeout.tv_usec=5000; if((fd_num=select(fd_max+1, &cpy_reads, 0, 0, &timeout))==-1) //오류 발생시(-1일때) break; if(fd_num==0) // timeout 발생 continue; for(i=0; i<fd_max+1; i++) // 폴링방식으로 계속 체크 { if(FD_ISSET(i, &cpy_reads)) { if(i==serv_sock) // 문제3. 클라이언트 소켓 접속 허용 { adr_sz=sizeof(clnt_adr); clnt_sock= accept(serv_sock, (struct sockaddr*)&clnt_adr, &adr_sz); FD_SET(clnt_sock, &reads); if(fd_max<clnt_sock) fd_max=clnt_sock; printf("connected client: %d \n", clnt_sock); read(clnt_sock, buf, BUF_SIZE); sock_check = clnt_sock; //클라이언트 소켓 번호를 sock_check 변수에 저장 aa[sock_check].sock_num = clnt_sock; //구조체에 저장 strcpy(aa[sock_check].id, buf); aa[sock_check].id[strlen(aa[sock_check].id) -1] = '\0'; printf("------------------------------\n"); printf("[ID: %s] entered\n", aa[sock_check].id); printf("------------------------------\n"); memset(buf, 0, BUF_SIZE); } else // read message! { str_len=read(i, buf, BUF_SIZE); if(str_len==0) // 접속해제 { FD_CLR(i, &reads); close(i); printf("------------------------------\n"); printf("closed client: %d \n", i ); printf("[ID: %s] disconnected\n", aa[i].id); // 문제8. 접속 해제 정보 출력 printf("------------------------------\n"); } else { printf("[%s]:", aa[i].id); printf("%s\n", buf); // 클라이언트 로부터 전송한 데이터 출력 write(i, buf, str_len); memset(buf, 0, BUF_SIZE); } } } } } close(serv_sock); return 0; } void error_handling(char *buf) { fputs(buf, stderr); fputc('\n', stderr); exit(1); }
client
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/socket.h> #define BUF_SIZE 100 #define SERVER_IP "127.0.0.1" //문제1. 호스트 컴퓨터의IP #define SERVER_PORT "9987" //문제1. 포트번호 void error_handling(char *message); int main() { int sock; char message[BUF_SIZE]; int str_len; struct sockaddr_in serv_adr; sock=socket(PF_INET, SOCK_STREAM, 0); //문제4. 소켓 생성 if(sock==-1) error_handling("socket() error"); memset(&serv_adr, 0, sizeof(serv_adr)); //문제4. 서버주소정보 serv_adr.sin_family=AF_INET; serv_adr.sin_addr.s_addr=inet_addr(SERVER_IP); serv_adr.sin_port=htons(atoi(SERVER_PORT)); if(connect(sock, (struct sockaddr*)&serv_adr, sizeof(serv_adr))==-1) //문제4. 서버접속 error_handling("connect() error!"); else puts("Connected..........."); printf("enter ID: "); // 문제5. ID 정보 전송 char id[20] = { 0, }; fgets(id, 20, stdin); write(sock, id, strlen(id)); id[strlen(id) - 1] = '\0'; printf("------------------------------\n"); printf("ID: %s entered\n", id); printf("------------------------------\n"); while(1) { fputs("Input message(Q to quit): ", stdout); fgets(message, BUF_SIZE, stdin); if(!strcmp(message,"q\n") || !strcmp(message,"Q\n")) break; write(sock, message, strlen(message)); str_len=read(sock, message, BUF_SIZE-1); message[str_len]=0; printf("Message from server: %s", message); // 문제 6. 서버에서 클라이언트로 다시 되돌려준 메세지 출력 } close(sock); return 0; } void error_handling(char *message) { fputs(message, stderr); fputc('\n', stderr); exit(1); }
'임베디드 > C언어 소켓 통신' 카테고리의 다른 글
리눅스 개발 환경 - vmware 우분투 설치 (0) | 2020.12.24 |
---|---|
makefile (0) | 2020.10.08 |
구조체 사용 (0) | 2020.10.08 |
enterID - 개행문자 없애기 (0) | 2020.10.06 |
echo_client.c echo_selectserv.c (0) | 2020.09.29 |