1:1 소켓 서버에서 반복적으로 소켓 열고 닫을때 이상 종료

juju1998의 이미지

안녕하세요?
Client와 1:1로만 통신하는 소켓 서버 프로그램을 소소들을 짜집기해서 만들었습니다.
기본 동작은 잘하는데 서버 테스트용으로 분간격으로 서버에 재접속하는 프로그램이 있습니다. 이녀석을
이용해서 반복 테스트를 해보면 3시간 정도 지나면 errnum = 1(operation not permitted)가 뜨면서
서버 프로그램이 죽습니다. 검토를 해봤는데 원인을 딱히 못찼겠네요.
linux kernel 2.4.1을 사용중입니다.
소스는 아래 첨부했습니다. 소켓옵션은 reuseaddr 및 keep alive time 옵션만 줬습니다.
초보라 원인 찾는데 뭐가 틀렸는지를 모르니 죽겠습니다. ㅜ.ㅜ
의견좀 부탁드립니다.

pthread_mutex_lock(&lan_handle_mutex);
LAN_HANDLE = -1;
pthread_mutex_unlock(&lan_handle_mutex);
res = listen(LAN_SOCKET_FD, 5);
if(res < 0)
{
PRINT_ERR(res, "LAN_SOCKET_LISTEN ERR");
exit(1);
}
while(1)
{
pthread_mutex_unlock(&lan_handle_mutex);
FD_ZERO(&readfds);
FD_SET(LAN_SOCKET_FD, &readfds);
if(LAN_HANDLE == 1)
FD_SET(LAN_CLIENT_FD, &readfds);
pthread_mutex_unlock(&lan_handle_mutex);
testfds = readfds;
result = select(FD_SETSIZE, &testfds, (fd_set *)NULL, (fd_set *)NULL, (struct timeval *)0);
for(fd = 0 ; fd <= FD_SETSIZE ; fd++)
{
if(FD_ISSET(fd, &testfds))
{
if(fd == LAN_SOCKET_FD) // client에서 socket 접속 요구가 들어오면...
{
client_len = sizeof(client_address);

client_sockfd = accept(LAN_SOCKET_FD, (struct sockaddr *)&client_address,
&client_len);
if(client_sockfd > 0)
{
pthread_mutex_lock(&lan_handle_mutex);
res = getpeername(client_sockfd, (struct sockaddr *)&client_address,&client_len);
if(res<0)
{
PRINT_ERR(res, "GET PEER NAME ERR");
close(client_sockfd);
pthread_mutex_unlock(&lan_handle_mutex);
}
if(client_address.sin_addr.s_addr != wallpad_ipAddr)
{
PRINT("WRONG TCP/IP WALLPAD CLIENT %d: %s",client_sockfd, inet_ntoa(client_address.sin_addr));
// IP FILTERING
close(client_sockfd);
pthread_mutex_unlock(&lan_handle_mutex);
}
else
{

if(LAN_HANDLE > 0)
{
close(LAN_CLIENT_FD); // 이전 Connnection Close
}
LAN_HANDLE = 1;
LAN_CLIENT_FD = client_sockfd;
FD_ZERO(&readfds);
FD_SET(LAN_SOCKET_FD, &readfds);
FD_SET(LAN_CLIENT_FD, &readfds);
pthread_mutex_unlock(&lan_handle_mutex);
PRINT("TCP/IP HA CLIENT ADDED");
addrl = inet_ntoa(client_address.sin_addr);
printf("HA IPaddr : %s\n", addrl);
f_ha_gas_request = 1;
f_ha_gas_alarm = 1;
// gas 상태 요청
t_data.length = FIXED_CPSG_DATA;
MAKE_CPSG_DEV_REQUEST(t_data.buff, DEV_TYPE_GAS);
LIST_ADD(RS232_CPSG, t_data);
// HA 상태 요청
t_data.length = HA_PACKET_LEN;
MAKE_WALLPAD_ST_REQUEST(t_data.buff);
LIST_ADD(WALLPAD, t_data);
}
}
else
{
PRINT_ERRNO("IF(FD==LAN_CLIENT_FD) BUT SOME WRONG");
// handle err
}
}
// Disconnect or Receive Data
else if(fd == LAN_CLIENT_FD) // HA Client로 부터 Data 수신됐을때..
{
pthread_mutex_lock(&lan_handle_mutex);
if(LAN_HANDLE == 1)
{
pthread_mutex_unlock(&lan_handle_mutex);
// check buff is available
if(ioctl(fd, FIONREAD, &nread) < 0) // ioctl function call error
{
PRINT("SOME WRONG");
// handle err
}
else
{
if(nread == 0)
{
// PRINT("DISCONNECTED");
pthread_mutex_lock(&lan_handle_mutex);
LAN_HANDLE = -1;
pthread_mutex_unlock(&lan_handle_mutex);
close(fd);
FD_CLR(fd, &readfds);
PRINT("REMOVE HA CLIENT");
}
else
{
memset(rx_buff, 0x00, ETHER_CLIENT_RCV_BUFF);

nread = READ_CLIENT_SOCKET(fd, rx_buff);
if(nread < 0)
{
pthread_mutex_lock(&lan_handle_mutex);
LAN_HANDLE = -1;
pthread_mutex_unlock(&lan_handle_mutex);
close(fd);
FD_CLR(fd, &readfds);
PRINT("IN CLIENT READ ROUTINE : REMOVE CLIENT");
}
else
{
if((nread == 6)||(nread == 7)||(nread == HA_PACKET_LEN))
LAN_DATA_PROCESS(fd,rx_buff, nread);
else
{
// FD_ZERO(&readfds);
// pthread_mutex_lock(&lan_handle_mutex);
// FD_SET(LAN_SOCKET_FD, &readfds);
// FD_SET(LAN_CLIENT_FD, &readfds);
// pthread_mutex_unlock(&lan_handle_mutex);
PRINT(" IN CLIENT READ ROUTINE : WRONG SIZE DATA ARRIVED");
}
}
} // end of else(nread == 0)
} // end of else(ioctl < 0)
}
else
{
pthread_mutex_unlock(&lan_handle_mutex);
} // end of if(LAN_HANDLE == 1)
} // end of if(fd = LAN_CLIENT_FD)

if(result < 0)
{
// handle err ...
PRINT_ERRNO("LAN SELECT FUNCTION ERROR");
FD_ZERO(&readfds);
pthread_mutex_lock(&lan_handle_mutex);
FD_SET(LAN_SOCKET_FD, &readfds);
if(LAN_HANDLE == 1)
FD_SET(LAN_CLIENT_FD, &readfds);
pthread_mutex_unlock(&lan_handle_mutex);
}

} // end of if(FD_ISSET..)
} // end of for(fd .. )
} // end of while

juju1998의 이미지

해당 소켓에 데이터를 쓸때 유효한 FD인지를 체크를 하니 죽는 증상이 사라지네요.
무식하게 signal(SIGPIPE, SIG_IGN)해도 잘 동작하지만 ....
하지만 단지 소켓을 열고 닫음을 반복할뿐이고 연결돼 있을때만 데이터를 씁니다.
근데 왜 FD가 틀린 순간 데이터가 써지는건지 모르겠네요..전부 mutex로 막아놨는데요.
요건 몰르겠어요..ㅠ.ㅠ

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.