BBS > c

C Socket client

작성자 : 이창우 (x1wins) | 등록일 : 2011-12-16 | 목록
첨부 파일이 없습니다.
첨부 이미지가 없습니다.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> 
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <pthread.h>
     
#define BUF_SIZE 300
#define NAME_SIZE 20
#define MODE_SIZE 20
     
void * send_msg(void * arg);
void * recv_msg(void * arg);
void error_handling(char * msg);

char mode[MODE_SIZE]="[default]";     
char name[NAME_SIZE]="[DEFAULT]";
char msg[BUF_SIZE]; //길이정보2바이트 와 메세지 종류 2바이트 추가.
char invite_name[20]; //초대할 사람이름을 위한 변수선언.
char host_name[20]; //초대요청한 사람이름을 위한 변수선언.
char an_swer[10]; //초대요청에 응할지 대답 y or n.
char re_an_swer[10]; // start모드에서의 돌아온 대답.   
char packetsort[10]; //패킷 종류를 알려줄 처음의 패킷.
int packetsize; //보내는 메세지의 길이를 알려줄 변수.
char packetbuf[BUF_SIZE+12];
// 패킷사이즈에 대해 점검해보자. 문자/ 숫자/ int형 char형 string형은 어떻게 다른가.

 
int main(int argc, char *argv[])
{
    int sock;
    int start_cycle = 1;   //스타트 사이클을 위한 변수
    int wait_cnt  = 1;   //wait 모드중입니다 한번 출력위해.
    struct sockaddr_in serv_addr;
    pthread_t snd_thread, rcv_thread;  //보내기 받기를 위한 쓰레드 선언.
    void * thread_return;
    if(argc!=5) {
        printf("Usage : %s <IP> <port> <name> <mode(start/wait)> \n", argv[0]);
        exit(1);
     }
     
    sprintf(name, "%s", argv[3]); //입력받은값을 이름에 저장.
    sprintf(mode, "%s", argv[4]);     //입력받은 모드를 mode에 저장.
    sock=socket(PF_INET, SOCK_STREAM, 0); //소켓 생성.
     
    memset(&serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family=AF_INET;
    serv_addr.sin_addr.s_addr=inet_addr(argv[1]);
    serv_addr.sin_port=htons(atoi(argv[2]));
      
    if(connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr))==-1)
        error_handling("connect() error");
    printf("서버 커넥팅 완료\n");
    // ---- 여기까지로 해서 서버와 연결해서 커넥팅완료 ----- //

    strcpy(packetsort, "m_name"); //서버에다가 저장을 위한 이름만  전송하는 모드.
    memset(&msg, 0x00, strlen(msg));   

    memcpy(&msg, &name, strlen(name)); //현재 문제점.
    packetsize = strlen(msg); //실전송용 메세지의 사이즈 측정.

    printf("전송내용 사이즈 : %d    ", packetsize);  //테스트용.
    printf("전송자 이름 : %s      \n", name);      //테스트용.
    printf("msg내용 : %s \n",msg);          //test용.

    memset(&packetbuf, 0x00, sizeof(packetbuf));   
    if(memcpy(&packetbuf[0],&packetsize,2)==NULL)
            error_handling("패킷만들기(사이즈) 에러"); // 패킷의 첫번째 부분에 패킷사이즈 표시.
    if(memcpy(&packetbuf[2],packetsort,10)==NULL)
            error_handling("패킷만들기(종류) 에러"); //패킷의 두번째에 패킷종류 표시.
    if(memcpy(&packetbuf[12],msg,packetsize)==NULL)
            error_handling("패킷만들기(내용)에러"); //패킷의 세번ㅤㅉㅒㅤ 부분에 실제 내용표시.
    printf("전송하는 패킷 내용:\n ");

 
    if(write(sock, packetbuf, sizeof(packetbuf))==-1)
         error_handling("first write(name전달) error");//  내이름을 전송.
       puts(&packetbuf[2]); //테스트용.
        puts(&packetbuf[12]);

while(1) //start or wait 모드를 무한반복 돌림.
{//1   
    if( strcmp(mode, "start")==0)
   {//2       
        while( start_cycle == 1)
    {//3
        printf(" start 모드중입니다. 초대할 사람의 이름을 입력하세요.\n");
        fgets(invite_name,20,stdin); //스트림으로부터 초대할 사람이름을 입력받는다.
       
            memset(&packetbuf, 0x00, sizeof(packetbuf));   
    if(memcpy(&packetbuf[0],&packetsize,sizeof(int))==NULL)
            error_handling("패킷만들기(사이즈) 에러"); // 패킷의 첫번째 부분에 패킷사이즈 표시.
    if(memcpy(&packetbuf[2],packetsort,10)==NULL)
            error_handling("패킷만들기(종류) 에러"); //패킷의 두번째에 패킷종류 표시.
    if(memcpy(&packetbuf[12],msg,packetsize)==NULL)
            error_handling("패킷만들기(내용)에러"); //패킷의 세번ㅤㅉㅒㅤ 부분에 실제 내용표시.

        write(sock, invite_name, strlen(invite_name)); //초대할 사람 이름 전송
        read(sock, re_an_swer, strlen(re_an_swer));
       
    if( strcmp(re_an_swer, "y")==0)
        {//4
         start_cycle = 0; //사이클이 돌지 않도록 변수값 변경.
         pthread_create(&snd_thread, NULL, send_msg, (void*)&sock);
         pthread_create(&rcv_thread, NULL, recv_msg, (void*)&sock);
         pthread_join(snd_thread, &thread_return);
         pthread_join(rcv_thread, &thread_return);
         close(sock);
           }  //4
    }//3
       
  }//2


    if(strcmp(mode, "wait")==0)
         {//5   
            if(wait_cnt == 1) //wait모드중입니다. 출력을 한번만.
            {
                printf(" wait 모드중입니다. \n");
                wait_cnt = 0;
            }
        if(read(sock, host_name, strlen(host_name))!= -1) // 소켓으로부터 초대요청한 사람의 이름을 읽는다.
        {//6    printf(" %c 님이 초대하였습니다. \n 응하시겠습니까? (y or n)\n",host_name);
            fgets(an_swer,1,stdin);
            write(sock, an_swer,sizeof(an_swer)); // 대답을 서버로 전송. y or n.
        }//6
    }//5
    sleep(10); //test용.
    if(strcmp(an_swer,"y")==0)  //대답이 y면 대화 실행.
    {//7
     pthread_create(&snd_thread, NULL, send_msg, (void*)&sock);
     pthread_create(&rcv_thread, NULL, recv_msg, (void*)&sock);
     pthread_join(snd_thread, &thread_return);
     pthread_join(rcv_thread, &thread_return);
     close(sock); 
    }//7

} //1 while문의 종료     

    return 0;
}
     
void * send_msg(void * arg)   // send thread main
{
    int sock=*((int*)arg);
    char name_msg[NAME_SIZE+BUF_SIZE];
    while(1) 
    {
        fgets(msg, BUF_SIZE, stdin);
        if(!strcmp(msg,"q\n")||!strcmp(msg,"Q\n")) 
        {
            close(sock);
            exit(0);
        }
        sprintf(name_msg,"%s %s", name, msg);
        write(sock, name_msg, strlen(name_msg));
    }
    return NULL;
}
     
void * recv_msg(void * arg)   // read thread main
{
    int sock=*((int*)arg);
    char name_msg[NAME_SIZE+BUF_SIZE];
    int str_len;
    while(1)
    {
        str_len=read(sock, name_msg, NAME_SIZE+BUF_SIZE-1);
        if(str_len==-1) 
            return (void*)-1;
        name_msg[str_len]=0;
        fputs(name_msg, stdout);
    }
    return NULL;
}
     
void error_handling(char *msg)
{
    fputs(msg, stderr);
    fputc('\n', stderr);
    exit(1);
}

20대. 꿈과 사랑과 용기와 희망과 열정을 가진 사나이.^^ 폴이 나에게 줌
로그인 하셔야 댓글을 사용하실수 있습니다.
댓글쓰기를 누르면 로그인 페이지로 이동 후 돌아옵니다.
총 댓글 겟수 1
이창우(x1wins) | 2011-12-16
패킷에 받는 사람 추가 요망
번호 제목 등록일 작성자 조회수
601 동적라이브러리 (0) 2012-12-20 이창우 3066
-> C Socket client (1) 2011-12-16 이창우 3547
407 폴이 나에게 준 C Socket (0) 2011-12-16 이창우 3519
142 정렬 (0) 2011-05-30 이창우 3676
< 1 >
글쓰기 검색