UDP 데이터그램 통신에서 서버가 recvfrom 부터 계속 대기상태가 됩니다.

dltkddyd의 이미지

클라이언트에서 서버로 데이터를 UDP를 이용해 보내는 프로그램을 만들었습니다. 그런데 클라이언트에서 서버로 데이터를 보냈더라도, 서버가 제대로 그 데이터를 받지 못하고 계속 대기상태로 머뭅니다. 각 소스는 다음과 같습니다.

클라이언트 소스
-sendto.cc-

#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <fcntl.h>
#include <cstdio>
#include <iostream>
using namespace std;
#include <cstring>
#include <signal.h>
#include <cstdlib>
 
 
 
#define BUFFER_SIZE 5
#define RESULT_BUFFER_SIZE 1024
#define RESULTFILE  "resultfile"
 
//#define TEST
 
static int socketfd;
static int acceptfd;
static int resultfd;
static char buffer[BUFFER_SIZE];
static char resultbuffer[RESULT_BUFFER_SIZE];
 
static void handleSIGINT(int sig) {
  //close(acceptfd);
  close(resultfd);
  string rm("rm -f ");
  rm+=RESULTFILE;
  system(rm.c_str());
  close(acceptfd);
  close(socketfd);
  kill(0,SIGKILL);
}
 
int main() {
  if(socketfd>=0) {
    close(socketfd);
  }
  if((socketfd=socket(AF_INET,SOCK_STREAM,0))==-1) {
    perror("socket error message : ");
    exit(0);
  }
  #ifdef TEST
    printf("socket success\n");
  #endif
  struct sigaction actionplan;
  sigemptyset(&actionplan.sa_mask);
  actionplan.sa_flags=0x0;
  actionplan.sa_handler=handleSIGINT;
  while(sigaction(SIGINT,&actionplan,0)==-1) {
    printf("Registerring handleSIGINT handler\n");
  }
  struct sockaddr_in iserver;
  iserver.sin_family=AF_INET;
  iserver.sin_addr.s_addr=inet_addr("112.145.252.108");
  iserver.sin_port=htons(60000);
  memset(iserver.sin_zero,0,8);
  while(bind(socketfd,(struct sockaddr*)&iserver,sizeof(struct sockaddr))==-1) {
    perror("bind error message : ");
    sleep(2);
  }
  #ifdef TEST
    printf("bind success\n");
  #endif
  if(listen(socketfd,10)==-1) {
    perror("listen error message : ");
  }
  #ifdef TEST
    printf("listen success\n");
  #endif
  struct sockaddr_in client;
  socklen_t size;
 
  if((acceptfd=accept(socketfd,(struct sockaddr*)&client,&size))==-1) {
    perror("accept Error message : ");
    exit(0);
  }
  #ifdef TEST
    printf("accept success\n");
    printf("The connected client ip is %s\n",inet_ntoa(client.sin_addr));
  #endif
 
  memset(buffer,0,sizeof(buffer));
  int length,llength;
    #ifdef TEST
      printf("ee\n");//test
      int loop=0;
    #endif
  string command("");
 
  string rm("rm -f ");
  rm+=RESULTFILE;
 
while(1) {
  command="";
  while((length=recv(acceptfd,buffer,sizeof(buffer),0))>0) {
    #ifdef TEST
      loop++;
      printf("%s\n",buffer);
      printf("The loop is %d\n",loop);
      printf("The length is %d\n",length);
    #endif
    if(buffer[strlen(buffer)-1]=='\n') {
      buffer[strlen(buffer)-1]=0;
      command+=buffer;
      break;
    }
    command+=buffer;
    memset(buffer,0,sizeof(buffer));
  }
  system(rm.c_str());
  command+=">"+string("")+RESULTFILE;
  #ifdef TEST
    printf("The executed command is : %s\n",command.c_str());
  #endif
 
  memset(resultbuffer,0,sizeof(resultbuffer));
  int is_executed=system(command.c_str());
  command+="";
  #ifdef TEST
    printf("The returned value is %d after system function was called.\n",is_executed);
  #endif
 
  char tmp[1];tmp[0]=EOF;
  if(is_executed!=0) {
    sprintf(resultbuffer,"system error %d",is_executed);
    send(acceptfd,resultbuffer,sizeof(resultbuffer),0);
    send(acceptfd,tmp,sizeof(tmp),0);
  }
 
 
  if((resultfd=open(RESULTFILE,O_RDONLY))==-1) {
    perror("open error message : ");
  }
  else {
    printf("The file is opened.\n");
  }
 
  while((length=read(resultfd,resultbuffer,sizeof(resultbuffer)))>0) {//\uba85\ub839 \uc2e4\ud589\uc758 \uacb0\uacfc\ub97c \uc0c1\ub300\ud3b8\uc5d0\uac8c \ub0b4\ubcf4\ub0b8\ub2e4.
    while((llength=send(acceptfd,resultbuffer,strlen(resultbuffer),0))>0) {
//printf("sending...\n");//test
      printf("%s",resultbuffer);//test
      memset(resultbuffer,0,sizeof(resultbuffer));
    }
  }
  //if(length==0) {
    printf("finishing...\n");//test
    printf("00000\n");//test
    memset(resultbuffer,0,sizeof(resultbuffer));
    //resultbuffer[0]=EOF;
    llength=send(acceptfd,tmp,sizeof(tmp),0);
    printf("llength is %d\n",llength);//test
    memset(resultbuffer,0,sizeof(resultbuffer));
  //}
  close(resultfd);
}
 
 
  close(acceptfd);
  close(resultfd);
  system(rm.c_str());
  close(socketfd);
  return 0;
}

서버소스
-recvfrom.cc-

#include <sys/socket.h>
#include <cstdio>
#include <cstdlib>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <unistd.h>
#include <cstring>
 
#define TEST
 
static int socketfd;
static void handleSIGINT(int sig) {
  close(socketfd);
  kill(0,SIGKILL);  
 
}
 
int main() {
  char buffer[10];
  if((socketfd=socket(AF_INET,SOCK_DGRAM,0))==-1) {
    perror("socket error message : ");
    exit(0);
  }
  struct sigaction actionplan;
  sigemptyset(&actionplan.sa_mask);
  actionplan.sa_flags=0x0;
  actionplan.sa_handler=handleSIGINT;
  while(sigaction(SIGINT,&actionplan,0)==-1) {
    printf("Registerring sigaction\n");
  }
 
  struct sockaddr_in server;
  server.sin_family=AF_INET;
  server.sin_addr.s_addr=inet_addr("112.145.252.108");
  server.sin_port=htons(60000);
  memset(server.sin_zero,0,8);
 
  if(bind(socketfd,(struct sockaddr*)&server,sizeof(struct sockaddr))==-1) {
    perror("bind error message : ");close(socketfd);exit(0);
  }
  /*if(listen(socketfd,5)==-1) {
    perror("listen error message : ");close(socketfd);exit(0);
  }*/
 
 
 
 
  struct sockaddr_in client;
  socklen_t size=(socklen_t)sizeof(client);
  int length;
  #ifdef TEST
    printf("Before recvfrom\n");
  #endif
  while((length=recvfrom(socketfd,buffer,sizeof(buffer),0,(struct sockaddr*)&client,&size))>0) {
    printf("%s\n",buffer);
  }
  /*while((length=read(socketfd,buffer,sizeof(buffer)))>0) {
    printf("%s\n",buffer);
  }*/
  if(length==-1) {
    perror("recvfrom error message : ");close(socketfd);exit(0);
  }
  else if(length==0) {
    printf("no message\n");
  }
  #ifdef TEST
    printf("After recvfrom\n"); 
  #endif
 
  close(socketfd);
  return 0;
}

서버를 먼저 구동한 상태에서 클라이언트를 구동했습니다. 데이터를 서버가 받지 못하길래 서버에서

netstat -anop|grep 60000

을 했더니 다음과 같은 식으로 내용이 출력됩니다.

udp 0 0 112.145.252.108:60000 0.0.0.0:* 6430/./recvfrom off(0.00/0/0)

dltkddyd의 이미지

서버의 어디를 고쳐야 데이터를 UDP 방식으로 받을 수 있나요?

본인 맞습니다.
인증샷
우헤헤헤... 로 대신합니다.

dltkddyd의 이미지

포트를 udp로 열었어야 했는데, tcp로 열었더군요. udp로 바꿔서 해결했습니다. 질문 올리고 바로 생각이 나는 것은 무슨 까닭인지....

본인 맞습니다.
인증샷
우헤헤헤... 로 대신합니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.