소켓프로그래밍에서 접속자를 연결리스트로 저장하는 것인데요....

ch0nn0m의 이미지

클라이언트가 서버에 접속할때 이름을 넣고...그 이름이 서버에 연결리스트로 저장되게 만들어보고 있었는데요...
클라이언트에서 전송할때는 문제없이 맞게 전송되는거 같은데...
서버에서 받을때는 이상하게 받네요...?
어디가 잘못된건지...부탁드립니다

서버

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<sys/types.h>
#include<sys/socket.h>
 
#define PORT 8888
 
typedef struct _user
{
        char name[20];
        struct _user *next;
}user;
user *head, *tail;
 
void init(void)
{
        head=(user*)malloc(sizeof(user));
        tail=(user*)malloc(sizeof(user));
        head->next=tail;
        tail->next=tail;
}
 
void add_user(char *str)//사용자저장
{
        int i;
        user *t;
        t=(user*)malloc(sizeof(user));
        str[strlen(str)]=0;
        printf("str=%s\n", str);
        sprintf(t->name,"%s",str);
        t->next=head->next;
        head->next=t;
}
void print()
{
        user *p;
        p=head->next;
        while(p!=tail)
        {
                printf("%s\n",p->name);
                p=p->next;
        }
}
 
int main(int argc, char **argv)
{
        init();
        char name[20];
        int serv_sock;
        int clnt_sock;
        struct sockaddr_in serv_addr;
        struct sockaddr_in clnt_addr;
        int clnt_size;
        pthread_t thread;
 
        if(argc!=2){
                printf("Usage : %s <port>\n", argv[0]);
                exit(1);
        }
 
        serv_sock=socket(PF_INET, SOCK_STREAM, 0);
        if(serv_sock==-1)
        {
                printf("socket() error\n");
                exit(1);
        }
        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(PORT);
        if(bind(serv_sock,(struct sockaddr*) &serv_addr, sizeof(serv_addr))==-1)
        {
                printf("bind() error\n");
                exit(1);
        }
        if(listen(serv_sock, 5)==-1)
        {
                printf("listen() error\n");
                exit(1);
        }
 
        while(1){
 
        clnt_size=sizeof(clnt_addr);
 
        clnt_sock=accept(serv_sock,(struct sockaddr*) &clnt_addr,&clnt_size);
 
        if(clnt_sock==-1)
        {
                printf("accept() error\n");
                exit(1);
        }
        read(clnt_sock,name,sizeof(name));
 
        printf("%s\n",name);   //클라이언트가 보낸 문장출력해서 확인하게 위한 코드
        printf("%d\n",strlen(name)); //클라이언트가 보낸 문장길이 확인하기 위한 코드
        printf("%s 님이 접속 하셨습니다...\n",name);
 
        add_user(name);  //접속자 추가
        print(); //접속자 출력
        printf("새로운 연결 클라이언트 ip: %s\n",inet_ntoa(clnt_addr.sin_addr));
        }
        return 0;
}

클라이언트

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<sys/types.h>
#include<sys/socket.h>
 
#define PORT 8888
 
char name[20];
char message[512];
 
int main(int argc,char **argv)
{
        int sock;
        int str_len;
        struct sockaddr_in serv_addr;
 
 
        if(argc !=4 ){
                printf("Usage : %s <IP> <port> <name>\n", argv[0]);
                exit(1);
        }
        sprintf(name, "[%s]", argv[3]);
 
        sock=socket(PF_INET,SOCK_STREAM,0);
        if(sock == -1)
        {
                printf("socket() error\n");
                exit(1);
        }
 
        memset(&serv_addr,0,sizeof(serv_addr));
        serv_addr.sin_family=AF_INET;
        serv_addr.sin_addr.s_addr=inet_addr(argv[1]);
        serv_addr.sin_port=htons(PORT);
 
        if(connect(sock,(struct sockaddr*)&serv_addr,sizeof(serv_addr))==-1)
        {
                printf("connect() error\n");
                exit(1);
        }
        write(sock,name,strlen(name));
 
        printf("%s\n",name); //클라이언트에서 보내는 문장 출력하는 코드
        printf("%d\n",strlen(name));  //클라이언트에서 보내는 문장길이 출력하는 코드
 
        close(sock);
        return 0;
}

결과가...
서버는...
[ch0nn0m@localhost tmp]$ ./test 8888
[YOYO]??
15
[YOYO]?? 님이 접속 하셨습니다...

-----접속자-----
[YOYO]??
----------------
새로운 연결 클라이언트 ip: 127.0.0.1

클라이언트는...
[ch0nn0m@localhost tmp]$ ./testc 127.0.0.1 8888 YOYO
[YOYO]
6

어디가 잘못된건가요???

dragonkun의 이미지

제 컴퓨터에선 문제없이 잘 돌아가네요.

한가지 의심이 가는 게 있는데.. name 을 0 으로 한 번 초기화 해 보세요.
---
Emerging the World!

Emerging the World!

spbrain의 이미지

int read_len = read(clnt_sock,name,sizeof(name)-1);
if (read_len > 0) name[read_len] = 0;
else {
//에러 처리
}

와 같이 수정하세요

댓글 달기

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