[완료]소켓통신 처리 제가 잘못한건가요?

mwizard의 이미지

클라이언트는 접속이 끊기면 자동으로 재접속을 요청합니다.

서버통신을 만들었는데 뭔가 이상한거 같아서요..

아래 코드가 이상한가 봐주세요..(특히 poll)

클라이언트는 두개면 연결을 유지합니다.

	int smppS_sockfd = 0;
	int smppR_sockfd = 0;
	struct pollfd fds[3];
	int state = 0;
	int clielen;
	int nRxt;
	int nReuseAddr = 1;
	int sockTmp = 0;
	int server_sockfd;
	stSmppPacket 	stData;
//이하 소켓 초기화부분 생략
	while(1)
	{
		bzero(&fds, sizeof(fds));
		fds[0].fd = server_sockfd;
		fds[0].events = POLLIN;
		fds[1].fd = smppS_sockfd;
		fds[2].fd = smppR_sockfd;
		fds[1].events = POLLIN;
		fds[2].events = POLLIN;
 
		nRxt = poll(fds, 1, 30);
		if(nRxt < 0)
			perror("poll error : ");
		else if(nRxt == 0)
			continue;
		else
		{ 
			if(fds[0].revents == POLLIN)
			{
				if ((sockTmp = accept(server_sockfd, (struct sockaddr *)&clientaddr, &clielen)) == -1)
				{
					perror("accept error : ");
					close(sockTmp);
				}
				bzero(&stData, sizeof(stData));
				if(recv(sockTmp, &stData, SMPP_PACKET_HEAD_SIZE, 0) < 0)
				{
					perror("recv error :");
					close(sockTmp);
				}else
				{//클라이언트에서 새로 요청이 왔다면 기존 연결이 끊겼기 때문이라 기존걸 닫고 새로 들어온걸 연결합니다.
					if(stData.ulCmdId == SMPP_BIND_TRANSMITTER)
					{
						if(smppS_sockfd)
							close(smppS_sockfd);
						smppS_sockfd = sockTmp;
					}
					else if(stData.ulCmdId == SMPP_BIND_RECEIVER)
					{
						if(smppR_sockfd)
							close(smppR_sockfd);
						smppR_sockfd = sockTmp;
					}
					else
					{
						bzero(szTmp, sizeof(szTmp));
						sprintf(szTmp, "Bind error[^d]", stData.ulCmdId);
						LogWrite(szTmp);
						close(sockTmp);
						return -1;
					}
					if(Recv(sockTmp, &stData) < 0)
						LogWrite("RecvBind error\n");
					sockTmp = 0;
 
			}
			else
			{
				bzero(&stData, sizeof(stData)); 
				if(fds[1].revents == POLLIN) // 이 부분
					sockTmp = smppS_sockfd;
				else if(fds[2].revents == POLLIN)
					sockTmp = smppR_sockfd;
				else
				{
					LogWrite("recv ???");
					continue;
				}	
				if(recv(sockTmp, &stData, SMPP_PACKET_HEAD_SIZE, 0) < 0)
				{
					perror("recv error:");
					close(sockTmp);
					return -1;
				}
 
				if(Recv(sockTmp, &stData) < 0)
					LogWrite("Recv error");
			}
		}
	}

위 코드에서 특히 제가 궁금한 부분이
fds[0] 에선 연결을 감시하고, 1, 2번에선 데이터 리시브가 있나 감시하려고 작성한 코드입니다.

제 의도가 그러했을때 위 처럼 작성하는게 맞나요?

bacon의 이미지

poll의 두번째 인자는 확실히 아닌것 같네요.

int poll(struct pollfd *fds, nfds_t nfds, int timeout);

감시할 디스크립트가 3개 이므로 3.

세번째 30 milliseconds는 의도 하신건지?

mwizard의 이미지

어느 소켓으로 메세지가 올지 모르기 때문에 타임아웃을 짧게 잡았어요..

현재 문제가 소켓 연결 후 바로 들어오는 메세지는 들어옵니다.

근데 그 다음에 들어오는 메세지가 안들어와요..

클라이언트에선 연결이 되자마자 연결 됐다는 메세지를 보내고,

그 다음에 보낼 메세지가 있으면 보내는데, 연결 됐다는 메세지 다음에는 받질 못하고 있습니다..;;

댓글 달기

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 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.