2012-10-16 3 views
0

나는 유닉스/리눅스 네트워킹 프로그래밍의 새로운 편이므로 아래에 서버 클라이언트 프로그램을 작성했다.이 코드에는 클라이언트와 서버 사이에 하나의 소켓이 있으며 서버에 대한 클라이언트 요청 , 1에서 100까지의 서버 응답을 클라이언트에 전달합니다. 그래서 내 질문에 우리가 스레드를 사용하지 않고 3 소켓 (TCP 연결)이 프로세스를 어떻게 할 수있다? 예를 들어 첫 번째 소켓이 실행되고 두 번째로 실행 된 다음 다시 세 번째로 실행됩니다. 다시 제안 사항이 있습니까?서버와 클라이언트 사이에 여러 개의 tcp 연결을 만드는 방법

는 Client.c

int main() 
{ 

int sock; 
struct sockaddr_in sa; 
int ret; 
char buf[1024]; 
int x; 

sock = socket (AF_INET, SOCK_STREAM, 0); 

bzero (&sa, sizeof(sa)); 
sa.sin_family = AF_INET; 
sa.sin_port = htons(SERVER_PORT); 
inet_pton (AF_INET, SERVER_IP, &sa.sin_addr); 

ret = connect (sock, 
(const struct sockaddr *) &sa,sizeof (sa)); 

if (ret != 0) { 
    printf ("connect failed\n"); 
    exit (0); 
} 

x = 0; 
while (x != -1) { 
    read (sock, buf , sizeof(int)); 
    x = ntohl(*((int *)buf)); 
    if (x != -1) 
    printf ("int rcvd = %d\n", x); 
} 

close (sock); 

exit (0); 

} 

Server.c는

int main() 
{ 

int list_sock; 
int conn_sock; 
struct sockaddr_in sa, ca; 
socklen_t ca_len; 
char buf[1024]; 
int i; 
char ipaddrstr[IPSTRLEN]; 

list_sock = socket (AF_INET, SOCK_STREAM, 0); 

bzero (&sa, sizeof(sa)); 
sa.sin_family = AF_INET; 
sa.sin_addr.s_addr = htonl(INADDR_ANY); 
sa.sin_port = htons(SERVER_PORT); 
bind (list_sock,(struct sockaddr *) &sa,sizeof(sa)); 

listen (list_sock, 5); 

while (1){ 

    bzero (&ca, sizeof(ca)); 
    ca_len = sizeof(ca); // important to initialize 
    conn_sock = accept (list_sock,(struct sockaddr *) &ca,&ca_len); 

    printf ("connection from: ip=%s port=%d \n",inet_ntop(AF_INET, &(ca.sin_addr), 
     ipaddrstr, IPSTRLEN),ntohs(ca.sin_port)); 

    for (i=0; i<100; ++i){ 

     *((int *)buf) = htonl(i+20); 
     // we using converting to network byte order 

     write (conn_sock, buf, sizeof(int)); 

    } 

    * ((int *)buf) = htonl(-1); 
    write (conn_sock, buf, sizeof(int)); 

    close (conn_sock); 

    printf ("server closed connection to client\n"); 

} 
} 
+0

당신을 수행 더 많은 정보를 얻을 서버가 세 개의 다른 소켓에서 회전하기를 원한다는 뜻입니까? 그런 다음 다른 포트가 필요합니다. 이게 니가 원하는거야? –

+0

예 그들은 3 개의 다른 소켓에서 회전하지만, 하나의 포트로 충분하다고 생각합니까? – lowcosthighperformance

+1

내가 아는 한 서버 소켓은 동일한 포트에 바인딩 할 수 없습니다. 그런 다음 연결을 "취해야"하는 것을 어떻게 결정해야합니까? 내가 볼 수있는 유일한 가능성은 소켓을 닫고 새 소켓을 여는 것입니다. 그러나 그 이득은 무엇입니까? –

답변

0

는 내가 가장이에 대한 내용이수록 우수한 자원 Beej's Guide to Netwokr Programming 볼 생각합니다. 그는 또한 당신이 출발점으로 사용할 수있는 좋은 예제를 가지고 있으며 그는 창문을 포함한 모든 주요 플랫폼을 다룹니다.

은 기본적으로 당신이 할 :

socket() 
bind() 
listen() 
accept() 

는 accept()를 고유 클라이언트에 연결된 소켓을 반환합니다. 그런 다음 select, poll 또는 epoll을 사용하여 해당 소켓에서 데이터를 사용할 수있는시기를 결정합니다. 이 API와 Beej의 가이드에 대한 맨 페이지를 살펴볼 것을 권한다. 처음으로 네트워크 프로그래밍을 배웠습니다.

코드를 보면 내부 루프가 잘못되었습니다. 연결을 수락하면 목록에 연결해야합니다. 현재, 당신은 그것을 덮어 쓰고 그것을 풀어 버린다. (e) 설문 조사를 사용하거나 데이터가있는 것을 알려주도록 선택해야합니다. 언제든지 그들 중 누구에게나 쓸 수 있습니다. Beej 's 가이드의 예제를 다시 보면 가장 도움이됩니다.

0

어쩌면 당신이 원하지 정확히 무엇을,하지만 난 당신이는 epoll을 시도 할 수 있다고 생각,

typedef struct event_loop 
{ 
    int max_event; 
    int epfd; 
}event_loop; 

event_loop* create_event_loop() 
{ 
    event_loop *ep = malloc(sizeof(event_loop)); 
    ep->max_event = 512; 
    ep->epfd = epoll_create(512); 
    return ep; 
} 
int add_event(event_loop *ep, int fd) 
{ 
    epoll_event ee; 
    ee.data.fd = fd; 
    ee.event = EPOLLIN | EPOLLPRI; 
    epoll_ctl(ep->epfd, EPOLL_CTL_ADD, fd, &ee); 
} 
void event_main(event_loop *ep, int listenfd) 
{ 
    epoll_event events[512]; 
    int nfds, i, newfd; 
    while(1) 
    { 
     if(nfds = epoll_wait(ep->epfd, events, 512, -1) == -1) 
      exit(1); 
     for(i = 0; i < nfds; i++) 
     { 
      if(events[nfds].data.fd == listenfd) 
      { 
       newfd = accept(listenfd, NULL, NULL); 
       add_event(ep, newfd); 
      } 
      else 
      { 
       //do what you want 
      } 
     } 
    } 
} 

는 epoll은 고효율 솔루션입니다 간단한 예제가, 그냥 man epoll

관련 문제