[완료]아래 코드 뭐가 문제일까요?(소켓, 메시지큐)

mwizard의 이미지

소켓 감시해서 수신이 있으면 처리하고 없으면 메시지큐 열어서
메시지큐 데이터 처리하고 메시지큐에 데이터 없으면 계속 감시하는 코드입니다.

문제는 되다 안되다 하는겁니다.
가장 먼저 실행하는 Bind를 하고 Bind Ack를 수신받는데 전송은 하는데 수신이 되다 안되다 합니다.

그 다음 큐에서 데이터를 읽어와 Deliver를 하는데 하다 안하다 합니다.(메시지 큐를 안읽어 옵니다.)

Deliver를 보낸 후 Deliver Ack를 받고 Report를 받는데, Report는 못받을 때가 훨씬 많습니다.

ps.
poll에서 마지막 인자인 타임아웃은 마이크로 세컨드 맞죠?
코드에서 ^ ==> % 입니다.(코드에 %가 들어가면 이상하게 보여서요..

typedef struct 
{
	long msgtype;
	char szText[TXT_LEN];
}MSGbuf;
 
int main(int argc, char* argv[])
{
	int nReuseAddr = 1;
	char szTmp[512] = {0};
	char szTemp[512];
	int j = 0;
	int nRxt;
	key_t key_id;
	MSGbuf buf;
	struct pollfd fds;
	Rhead head;
	fds.fd = nSock;
	fds.events = POLLNORM;
 
	if(strcmp(argv[1], "sktel") == 0)
		g_nType = SKTEL;
	else
		g_nType = KT;
 
	if(Connect() == 0)//소켓 연결(이 안에서 nSock 설정(글로벌 변수))
	{
		if(Bind(argv[1], argv[2]) < 0) //bind 함수 아닙니다.
		{
			close(nSock);
			LogWrite("Bind error!!");	
			if(Connect() == 0)
			{
				if(Bind(argv[1], argv[2]) < 0)
					return -1;
			}
			else
				return -1;
		}
 
		memset(&buf, 0x00, sizeof(buf));
 
		key_id = msgget((key_t)4978, IPC_CREAT|0666);
		if(key_id < 0)
		{
			perror("msgget error : ");
			return -1;
		}
 
		while(1)
		{
			memset(&head, 0x00, sizeof(head));
			memset(szTmp, 0x00, sizeof(szTmp));
			nRxt = poll(&fds, 1, 20);// 소켓 감시
 
			if(nRxt < 0)
			{
				printf("poll error");
				LogWrite("main() : poll error");
				return -1;		
			}
			else if(nRxt == 0)//소켓 감시하다 타임아웃으로 빠지면 메시지큐 데이터 검색
			{
				if(nRxt = msgrcv(key_id, (void*)&buf, sizeof(buf)-sizeof(long), g_nType, IPC_NOWAIT|MSG_NOERROR) != -1)
				{
					bzero(szTemp, sizeof(szTemp));
					sprintf(szTemp, "Text : ^s", buf.szText);
					LogWrite(szTemp);
					if(SendMsg(DELIVER, buf.szText) < 0) //데이터가 있으면 소켓 전송해야하나 여기로 잘 안들어 옴
						LogWrite("SendMsg error");
				}
				continue;
			}
			else if(nRxt > 0) //소켓에서 수신 데이터 있으면 처리
			{
				LogWrite("=====================================================");
				bzero(szTemp, sizeof(szTemp));
				bzero(&head,  sizeof(head));
				nRxt = recv(nSock, szTmp, sizeof(head), 0);
				sprintf(szTemp, "msgtype[^d] msgleng[^d]", head.msgtype, head.msgleng);
				LogWrite(szTemp);
				if(fds.revents == POLLNORM && nRxt > 0)
				{
					memcpy(&head, szTmp, sizeof(head));
					printf("recv head.msgtype[^d] size[^d]\n", head.msgtype, head.msgleng);
					switch (head.msgtype)
					{
					case REPORT:
						ReportRcv(head.msgleng);
						break;
					case DELIVER_ACK:
						if(DeliverAck() < 0)
							LogWrite("Deliver Ack error");
						break;
					case BIND_ACK:
						if(BindACK() < 0)
							LogWrite("Bind Ack error");
						break;
					default:
						bzero(szTmp, sizeof(szTmp));
						recv(nSock, szTmp, sizeof(szTmp), 0);
						LogWrite("recv error");
					}
				}
			}
			continue;
		}
	}
	else
	{
		close(nSock);
		LogWrite("Emul Connect fail");
		return -1;
	}
	return 0;
}

소켓 생성을 하기전에 fd에 소켓값을 넣어주니 poll에서 이벤트를 못받는건 당연한데...
참 멍청한 짓 했네요.. 사소한 실수로 3일을 버리다니...ㅡ.ㅜ;

mwizard의 이미지

..

mwizard의 이미지

아래코드를 실행 해 보니 소켓 수신만 받아 출력합니다.
본문과 아래 코드는 같은 문제라 판단되니 아래 코드에 대한 답변을 주셔도 됩니다.

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/sysinfo.h>
#include <netinet/in.h>
typedef	struct
{
	int		msgtype;
	int		msgleng;
}Rhead;
typedef struct 
{
	long msgtype;
	char szText[150];
}MSGbuf;
int main()
{
	struct pollfd fds;
	int nSock;
	struct sockaddr_in stAddress;
	int nConnected;
	int nReuseAddr = 1;
	char buff[1024];
	int nRxt;
	MSGbuf buf;
	int i = 0;
	key_t key_id;
	Rhead head;
	bzero(&head, sizeof(head));
	memset(&stAddress, 0x00, sizeof(stAddress));
 
	key_id = msgget((key_t)8899, IPC_CREAT|0666);
	stAddress.sin_family = AF_INET;
	stAddress.sin_port = 7788;
	stAddress.sin_addr.s_addr = inet_addr("127.0.0.1");
	nSock = socket(AF_INET, SOCK_STREAM, 0);
	setsockopt(nSock, SOL_SOCKET, SO_REUSEADDR, (char*)nReuseAddr, sizeof(nReuseAddr));
 
	nConnected = connect(nSock, (struct sockaddr *)&stAddress, sizeof(stAddress));
	fds.fd = nSock;
	fds.events = POLLNORM;
	printf("POLLNORM[^d]\n", POLLNORM);
	if(nConnected < 0)
	{
		close(nSock);
		return -1;
	}
	while(1)
	{
		nRxt = poll(&fds, 1, 20);
		if(nRxt < 0)
		{
			printf("poll error");
			return -1;		
		}
		else if(nRxt == 0)
		{
			if(msgrcv(8899, (void*)&buf, sizeof(buf)-sizeof(long), 0, IPC_NOWAIT|MSG_NOERROR) != -1)
				printf("msgrcv : ^s\n", buf.szText);	
			continue;
		}
		else if(nRxt > 0)
		{
			memset(buff, 0x00, sizeof(buff));
//			printf("POLLNORM[^d] fds.revents[^d]\n", POLLNORM, fds.revents);
			nRxt = recv(nSock, buff, 8, 0);
			memcpy(&head, buff, sizeof(head));
//			if(fds.revents == POLLNORM && nRxt >= 0)
//				printf("msgtype[^d] msgleng[^d]\n", head.msgtype, head.msgleng);
			bzero(buff, sizeof(buff));
			nRxt = recv(nSock, buff, sizeof(buff), 0);
//			printf("nRxt[^d]", nRxt);
			if(fds.revents == POLLNORM && nRxt >= 0)
				printf("recv : ^s\n", buff);
			else
				printf("fds.revents[^d] nRxt[^d] buff[^s]", fds.revents, nRxt, buff);
		}		
	}
	return 0;
}

mwizard의 이미지

msgrcv에서 첫번째 인자를 잘 못 넣었네요..;;
첫번째 인자를 key_id를 넣어주니 이건 잘 됩니다..

근데 본문은 어디가 잘못된걸까요?...;

댓글 달기

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