계속 반복하는 서버 클라이언트 프로그램을 만들려고 하는데 도와주세요.!

mengkyum의 이미지


제가 프로그래밍 하려는 것은

1. 타켓보드(linux)에서 1초마다 임의의 데이터를 windows-PC(client)로 받아오는 프로그램

2. 서버에서 임의의 명령어를 받을시 이미 저장되있던 파일을 windows-PC(client)로 보내는 프로그램

각각의 1,2, 소켓 프로그램을 구현하기 했서 이 2개를 합친다고 합쳤습니다.

동작 구현은 2번을 임의의 명령어로 동작시키고 1번에 해당하는 명령어를 치면 1번 동작을 하는 프로그램을

계속 반복하는 프로그램으로 만들려고

하는데 이게 자꾸 2번동작을 하고 나면 종료를 해버립니다.

while문으로 돌리는데도 자꾸 빠져나오는 이유가 뭘까요?.....'''''

조언좀 부탁드립니다.

//서버(linux) 소스
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
 
#define BUFSIZE 30
 
void data(void);
void error_handling(char *message);
char spectrum_data[BUFSIZE];
 
int main(int argc, char **argv)
{
	int serv_sd;
	int clnt_sd;
	int fd;
	char buf[BUFSIZE];
	char message[BUFSIZE];
	char command_start[BUFSIZE]="#start\n";
	char command_file_send[BUFSIZE]="#send\n";
 
 
 
	struct sockaddr_in serv_addr;
	struct sockaddr_in clnt_addr;
	int clnt_addr_size;
	int len;
	int str_len;
	int status;
 
	int j=0;
 
	if(argc!=2){
		printf("Usage : %s <port>\n", argv[0]);
		exit(1);
	}
 
	fd = open("/mnt/mmc/data.txt", O_RDONLY); 
	if(fd == -1)
	error_handling("File open error");
 
	serv_sd=socket(PF_INET, SOCK_STREAM, 0);   
	if(serv_sd == -1)
		error_handling("socket() error");
 
	memset(&serv_addr, 0, sizeof(serv_addr));
	serv_addr.sin_family=AF_INET;
	serv_addr.sin_addr.s_addr=htonl(INADDR_ANY);
	serv_addr.sin_port=htons(atoi(argv[1]));
 
	if( bind(serv_sd, (struct sockaddr*) &serv_addr, sizeof(serv_addr))==-1 )
		error_handling("bind() error");
 
	if( listen(serv_sd, 5)==-1 )
		error_handling("listen() error");
 
	clnt_addr_size=sizeof(clnt_addr);    
 
 
	clnt_sd=accept(serv_sd, (struct sockaddr*)&clnt_addr,&clnt_addr_size);
	if(clnt_sd==-1)
		error_handling("accept() error");
 
////////////////////////////////저장 파일 전송  /////////////////////////////////////////	
while(1){
		while( (str_len=read(clnt_sd, message,BUFSIZE)) != 0){
 
			write(1, message,str_len);
 
			if(!strcmp(message,command_file_send)){
 
					write(clnt_sd,command_file_send,str_len);
 
					//while(status==0){
						while( (len=read(fd, buf, BUFSIZE)) != 0){
							write(clnt_sd, buf, len);
 
						}
					//if(len==0)
					//status=1;
					//}
				//if(status==1)
				//break;
			}	
/////////////////////////////////  데이터 실시간 전송  ///////////////////////////////////////
			else if(!strcmp(message,command_start)){
 
				len=sizeof(spectrum_data);
 
				write(clnt_sd,command_start,str_len);
				while(1)
				{
					data();
					write(clnt_sd,spectrum_data,len);
					write(1, spectrum_data,len);
					sleep(1);
				}
			}
		//message[str_len]=0;
		return;
		}
	//message=0;
   return;
}
//////////////////////////////////////////////////////////////////////////////////////////////
 
 
	close(fd);
	close(clnt_sd);
	return 0;
}
void data(void)
{	
	char i;
        for(i=0;i<10;i++)
        {
                spectrum_data[i]= (0x30+(rand()%10));
					 spectrum_data[10]='\n';
        }
//return;
}
void error_handling(char *message)
{
	fputs(message, stderr);
	fputc('\n', stderr);
	exit(1);
}

//클라이언트(windows) 소스
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <windows.h>
 
#define BUFSIZE 30
void ErrorHandling(char *message);
 
int main(int argc, char **argv)
{
	WSADATA  wsaData;
	SOCKET   hSocket;
 
	char buf[BUFSIZE];
	char message[BUFSIZE];
	char command_start[BUFSIZE]="#start\n";
	char command_file_send[BUFSIZE]="#send\n";
	char spectrum_data[BUFSIZE];
	FILE* fp;
 
 
 
	SOCKADDR_IN servAddr;
	int len;
	int str_len;
	int status=0;
 
	if(argc!=3){
		printf("Usage : %s <IP> <port>\n", argv[0]);
		exit(1);
	}
 
	fp = fopen("C:\\ex\\data.txt", "w");
	if(fp == NULL)
	{
		ErrorHandling("File open error");
 
	}
 
	if(WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
		ErrorHandling("WSAStartup() error!");
 
	/* 서버 접속위한 소켓 생성 */
	hSocket=socket(PF_INET, SOCK_STREAM, 0);   
	if(hSocket == INVALID_SOCKET)
		ErrorHandling("socket() error");
 
	memset(&servAddr, 0, sizeof(servAddr));
	servAddr.sin_family=AF_INET;
	servAddr.sin_addr.s_addr=inet_addr(argv[1]);
	servAddr.sin_port=htons(atoi(argv[2]));
 
	if( connect(hSocket, (SOCKADDR*)&servAddr, sizeof(servAddr))==SOCKET_ERROR )
		ErrorHandling("connect() error!");
 
 
	while(1)
	{
		//status=0;
 
		fputs("-------COMMAND--------\n",stdout);
		fputs("1. #send = send file\n",stdout);
		fputs("2. #start = send data\n",stdout);
		fputs("----------------------\n",stdout);
		fputs("input command : ",stdout);
		fgets(message, BUFSIZE,stdin);
 
		send(hSocket,message,strlen(message),0);				//명령어 전송
		str_len=recv(hSocket,message,BUFSIZE-1,0);				//서버의 응답
//////////////////////////// 저장 파일 전송 ////////////////////////////
 
		if(!strcmp(message,command_file_send))
		{		
 
			//while(status==0){
 
				/* 데이터를 전송 받아서 파일에 저장한다 */
				while( (len=recv(hSocket, buf, BUFSIZE, 0)) != 0 )
				{
					fwrite(buf, sizeof(char), len, fp);
 
				}
				//if(len==0);
				//status=1;
 
			//}
			//if(status==1)
			//break;
		}
////////////////////////// 실시간 데이터 전송 ////////////////////////////		
 
		else if(!strcmp(message,command_start))
		{
			while(1){
 
				len=recv(hSocket, buf, BUFSIZE, 0);
 
				printf("%s",buf);
				printf("\n");
 
				Sleep(1000);
 
			}
		}
	return;
	}
/////////////////////////////////////////////////////////////////////////
 
	fclose(fp);
	closesocket(hSocket);
	WSACleanup();
	return 0;
}
 
void ErrorHandling(char *message)
{
	fputs(message, stderr);
	fputc('\n', stderr);
	exit(1);
}
chadr의 이미지

while( (str_len=read(clnt_sd, message,BUFSIZE)) != 0) 이 줄을 보시면 만약에 0이라면
루프가 종료되고 아래 return문에 의해 프로그램이 종료됩니다.
그리고 저 루프 블럭의 내부에서 루프의 맨 마지막에 return문에 보이네요.

루프 한번 돌면 프로그램이 종료될것 같군요.

그리고 tcp는 stream 형식이므로 read(clnt_sd, message,BUFSIZE))를 했을 때 버퍼에 클라이언트가
보낸 데이터가 한번에 다 안들어 올수 있습니다. 그부분 확인을 해보세요.

그리고 서버인데 실행후 한번 클라이언트의 접속을 처리하고 종료하실게 아니라면 accept를 계속
호출하여 다음 클라이언트를 기다리셔야 합니다.

디버거를 이용해보세요. 디버거를 한번도 이용해본적이 없으시면 이번기회에 배워보시구요.
디버거는 프로그래밍을 하는데 없어서는 안되는 도구이며 반드시 친해져야하는 도구입니다.

디버거를 이용하여 순차적으로 따라가시면서 변수의 내용이나 함수의 리턴값을 확인해보시면
어느 부분에 논리적 오류가 있는지 단번에 찾아내실 수 있습니다. 제가 보기에는 이 문제는
디버거를 이용해서 찾아보시면 금방 해결 하실수 있는 문제 같습니다.
-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.

-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.

댓글 달기

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