간단한 소켓프로그램인데요, 소켓 연결은 되는데 값이 저장이 안되는 것 같아요ㅠㅠ

익명 사용자의 이미지


cal_data라는 구조체를 만들어서 연산자와 피연산자를 넘겨주는건데요....
소켓 연결까지는 되는데, 리눅스에서 실행해보면(./프로그램명 연산자 피연산자 연산기호)
서버에서 계산한 답이 나와야 하는데 그냥 %d %c %d = %d 이렇게 문자가 뜹니다ㅋㅋㅠㅠㅠㅠㅠ

소켓프로그래밍을 이제 막 공부하는 중이라 잘못된 부분이 어디인지를 봐도 잘 모르겠어요ㅠㅠ
어디가 잘못된건가요?ㅠㅠㅠㅠㅠ

////////////////client-리눅스//////////////////

struct cal_data
{
int left_num;
int right_num;
char op;
int result;
short int error;
};

int main(int argc, char **argv)
{
struct sockaddr_in server_addr;
struct cal_data rdata;
int server_sockfd;
char buffer[256];
int len;
int left_num, right_num;

if(argc != 4)
{
perror("Usage : %s [num1] [num2] [0p]\n", argv[0]);
return 1;
}

rdata.left_num = atoi(argv[1]);
rdata.right_num = atoi(argv[2]);
rdata.op = argv[3][0];

server_sockfd = socket(AF_INET, SOCK_STREAM, 0);

if((server_sockfd = socket(AF_INET, SOCK_STREAM, 0) == -1))
{
perror("error :");
return 1;
}

memset((void *)&server_addr, 0x00, sizeof(server_addr));

server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
server_addr.sin_addr.s_addr = inet_addr(IP);

if(connect(server_sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1)
{
perror("connnect error :");
return 1;
}

rdata.left_num = htonl(rdata.left_num);
rdata.right_num = htonl(rdata.right_num);

read(server_sockfd, (void *)&rdata, sizeof(rdata));
rdata.error = 0;

write(server_sockfd, (void *)&rdata, sizeof(rdata));
rdata.error = 0;

if(ntohs(rdata.error != 0))
{
perror("CALC error %d\n", ntohs(rdata.error));
}
perror("%d %c %d = %d\n", ntohl(rdata.left_num), rdata.op, ntohl(rdata.right_num), ntohl(rdata.result));

close(server_sockfd);
return 0;
}

/////////////////////////server-윈도우/////////////////////////////
struct cal_data
{
int left_num;
int right_num;
char op;
int result;
short int error;
};

int main(int argc, char **argv)
{
WSADATA WSAData;
sockaddr_in client_addr, sock_addr;
SOCKET listen_s, client_s;
int len, addr_len;
struct cal_data sdata;
int left_num, right_num;
short int cal_result;
int recvn, sendn;

if(WSAStartup (MAKEWORD (2,2), &WSAData) != 0)
{
return 1;
}

listen_s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(listen_s == INVALID_SOCKET)
{
return 1;
}

ZeroMemory((void *)&sock_addr, sizeof(sock_addr));
sock_addr.sin_family = AF_INET;
sock_addr.sin_addr.s_addr = htonl(INADDR_ANY);
sock_addr.sin_port = htons(PORT);

if(bind(listen_s, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) == -1)
{
printf("Error ");
return 1;
}

if(listen(listen_s, 5) == -1)
{
printf("Error ");
return 1;
}

for(;;)
{
addr_len = sizeof(client_addr);
client_s = accept(listen_s, (struct sockaddr *)&client_addr, &addr_len);

if(client_s == -1)
{
printf("Error ");
return 1;
}

len = sizeof(sdata);

recvn = recv(client_s, (char *)&sdata, len, 0);
if(recvn != len)
{
return 1;
}

sdata.error = 0;
left_num = ntohs(sdata.left_num);
right_num = ntohs(sdata.right_num);

switch(sdata.op)
{
case '+':
cal_result = left_num + right_num;
break;
case '-':
cal_result = left_num - right_num;
break;
case '*':
cal_result = left_num * right_num;
break;
case '/':
if(right_num == 0)
{
sdata.error = 2;
break;
}
cal_result = left_num / right_num;
break;
default:
sdata.error = 1;
}

sdata.result = htonl(cal_result);
sdata.error = htons(cal_result);

sendn = send(client_s, (char *)&sdata, len, 0);
if(sendn != len)
{
return 1;
}
closesocket(client_s);
}

closesocket(listen_s);
WSACleanup();
return 0;

}

oosap의 이미지

일단 에코 서버/클라이언트 부터 만들어보세요.
지금 보니까 에코 서버/클라이언트를 만들기 위한 부분에서 문제가 있어요. 계산기 서버는 그 다음 단계 입니다.

말씀하신 것과 95% 쯤 똑같은 예제가 "열혈 TCP/IP 소켓프로그래밍 - 윤성우" 이라는 책에 있습니다. 혹시 지금 이책으로 공부하시는거 아닌가요? 너무 똑같은 주제라서요..

위 책 자료실에 보면 예제 코드가 있고 5장 예제 코드에 원하시는 정답에 해당하는 코드가 있어요..

그리고 소스코드는 여기 올릴 때 태그를 사용하세요..

'*' 대신 '<', '**' 대신 '>' 입니다.
*code**
server_sockfd = socket(AF_INET, SOCK_STREAM, 0);

if((server_sockfd = socket(AF_INET, SOCK_STREAM, 0) == -1))
{
perror("error :");
return 1;
}
*/code**

server_sockfd = socket(AF_INET, SOCK_STREAM, 0);
 
if((server_sockfd = socket(AF_INET, SOCK_STREAM, 0) == -1))
{
    perror("error :");
    return 1;
}

이렇게 하면 되요..

위 코드에서 문제가 바로 보이죠? socket 을 왜 두번 호출했나요? 먼저 만든 소켓은 고아가 되었네요..

Thanks for being one of those who care for people and mankind.
I'd like to be one of those as well.

익명 사용자의 이미지

감사합니다. 다시 한번 해봐야겠어요!

댓글 달기

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