2013-03-24 4 views
2

소켓 (서버 및 클라이언트 프로그램)을 만들고 해당 소켓을 사용하여 TCP 포트를 통해 메시지를 보내는 프로그램이 있습니다. 내 질문은, 어떻게 여러 메시지를 교환 할 수 있습니까? 메시지를 보낼 때마다 포트가 닫히고 다른 포트를 사용하여 다른 메시지를 보내야합니다.TCP 포트를 통해 여러 메시지 보내기

예를 들어, 클라이언트에서 서버로 2 개의 번호를 보내야하고 서버는 내가 보낸 번호의 총계를 답장해야합니다. 어떻게하면 동일한 포트를 통해 정의되지 않은 번호 또는 2 개의 번호를 전송할 수 있습니까? 여기

는 코드 (거의 표준 물건)입니다

서버 :

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 

char* Itoa(int value, char* str, int radix) 
{ 
    static char dig[] = 
     "" 
     "abcdefghijklmnopqrstuvwxyz"; 
    int n = 0, neg = 0; 
    unsigned int v; 
    char* p, *q; 
    char c; 
    if (radix == 10 && value < 0) { 
     value = -value; 
     neg = 1; 
    } 
    v = value; 
    do { 
     str[n++] = dig[v%radix]; 
     v /= radix; 
    } while (v); 
    if (neg) 
     str[n++] = '-'; 
    str[n] = '\0'; 
    for (p = str, q = p + (n-1); p < q; ++p, --q) 
     c = *p, *p = *q, *q = c; 
    return str; 
} 

void error (const char *msg) 
{ 
    perror (msg); 
    exit (1); 
} 
int main (int argc, char *argv[]) 
{ 
    if (argc < 2) 
    { 
     fprintf (stderr, "ERROR, no port provided\n"); 
     exit (1); 
    } 
    //nova varijabla za sumiranje primljenih brojeva 
    int suma=0; 

    int sockfd, newsockfd, portno,i; 
    socklen_t clilen; 
    char buffer[256]; 
    struct sockaddr_in serv_addr, cli_addr; 
    int n; 
    for (i=0;i<2;i++) 
    { 
     sockfd = socket (AF_INET, SOCK_STREAM, 0); 
     if (sockfd < 0) error ("ERROR opening socket"); 
     memset ((char *) &serv_addr, 0, sizeof (serv_addr)); 
     portno = atoi (argv[1]); 
     portno+=i; 
     serv_addr.sin_family = AF_INET; 
     serv_addr.sin_addr.s_addr = INADDR_ANY; 
     serv_addr.sin_port = htons (portno); 
     if (bind (sockfd, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) < 0) error ("ERROR on binding"); 
     //test za ispis otvorenog porta 
     printf("Uspjesno otvoren localhost na portu %d\n", portno); 
     listen (sockfd, 5); 
     clilen = sizeof (cli_addr); 
     newsockfd = accept (sockfd, (struct sockaddr *) &cli_addr, &clilen); 
     if (newsockfd < 0) error ("ERROR on accept"); 
     memset (buffer, 0, 256); 
     n = read (newsockfd, buffer, 255); 
     if (n < 0) error ("ERROR reading from socket"); 
     printf ("%d. proslan broj: %s\n", i+1, buffer); 
//print 
     suma=suma+atoi(buffer); 
//radi!!  printf("suma je %d\n", suma); 
//od klijenta: n = write (sockfd, buffer, strlen (buffer)); 
//char * itoa (int value, char * str, int base); 
     Itoa(suma, buffer, 10); 
     n = write (newsockfd, buffer, strlen(buffer)); 
     if (n < 0) error ("ERROR writing to socket"); 
     close (newsockfd); 
     close (sockfd); 
    } 
    return 0; 
} 

클라이언트 :

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <netdb.h> 
void error (const char *msg) 
{ 
    perror (msg); 
    exit (1); 
} 
int 
main (int argc, char *argv[]) 
{ 
    if (argc < 3) 
    { 
     fprintf (stderr, "usage %s hostname port\n", argv[0]); 
     exit (1); 
    } 
    int sockfd, portno, n,i; 
    struct sockaddr_in serv_addr; 
    struct hostent *server; 
    char buffer[256]; 
    for (i=0;i<2;i++) 
    { 
     portno = atoi (argv[2]); 
     sockfd = socket (AF_INET, SOCK_STREAM, 0); 
     if (sockfd < 0) 
     error ("Ne mogu otvoriti socket!"); 
     server = gethostbyname (argv[1]); 
     if (server == NULL) 
     { 
      fprintf (stderr, "Greska, ne postoji!\n"); 
      exit (1); 
     } 
     memset ((char *) &serv_addr, 0, sizeof (serv_addr)); 
     serv_addr.sin_family = AF_INET; 
     bcopy ((char *) server->h_addr, 
     (char *) &serv_addr.sin_addr.s_addr, 
     server->h_length); 
     portno+=i; 
     serv_addr.sin_port = htons (portno); 
     if (connect (sockfd, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) < 0) 
     error ("ERROR connecting"); 
     printf ("%d. broj za slanje: ", i+1); 
     memset (buffer, 0, 256); 
     fgets (buffer, 255, stdin); 
     n = write (sockfd, buffer, strlen (buffer)); 
     if (n < 0) 
     error ("ERROR writing to socket"); 
     memset (buffer, 0, 256); 
     n = read (sockfd, buffer, 255); 
     if (n < 0) 
     error ("ERROR reading from socket"); 
     if (i==1) printf ("Suma iznosi: %s\n", buffer); 
     close (sockfd); 
    } 
    return 0; 
} 

그래서, 예를 들어, 내가 코드를 실행하고이를 얻을 수 서버 측 :

[email protected] ~/Desktop/Mreze/Lab1/rijeseno $ ./server2 5000 
Uspjesno otvoren localhost na portu 5000 
1. proslan broj: 45 

Uspjesno otvoren localhost na portu 5001 
2. proslan broj: 56 

[email protected] ~/Desktop/Mreze/Lab1/rijeseno $ 
(210)

그리고 클라이언트 측 : 나는 전송하지만 성공하지와 일부 루프 있도록 while 루프를 넣어 시도했습니다

[email protected] ~/Desktop/Mreze/Lab1/rijeseno $ ./client2 localhost 5000 
1. broj za slanje: 45 
2. broj za slanje: 56 
Suma iznosi: 101 

. 제게 설명을 해줘서 어디에서 작동해야하는지 설명해주세요. 고맙습니다!

+0

소켓을 닫지 마십시오 여기

읽기 데이터에 대한 (매우 unoptimal, 아직 간단한) 코드? – Hasturkun

+0

이 원시 출력입니다. 너 필요해? –

+0

나는 항상 출력을 엉망으로 만든다. 누구든지 편집 해 주셔서 감사합니다. @Hasturkun, 나는 그것을 시도하고 연결을 다음 번에 클라이언트가 연결을 시도한 거부했다 – Juraj

답변

2

에 대한 문제입니다. 사실 데이터를 완전히 읽거나 EOF 조건 (-1 반환 값)을 감지 한 경우 데이터를 읽어야합니다.

일반적으로 스트림 프로토콜에서 메시지 경계가 어떤 형태로든 유지된다는 보장이 없으므로 부품을 수신 할 때보다 안정적인 코드를 작성해야합니다.

int readLine(int fd, char data[]) 
{ 
    size_t len = 0; 
    while (len < maxlen) 
    { 
     char c; 
     int ret = read(fd, &c, 1); 
     if (ret < 0) 
     { 
      data[len] = 0; 
      return len; // EOF reached 
     } 
     if (c == '\n') 
     { 
      data[len] = 0; 
      return len; // EOF reached 
     } 
     data[len++] = c; 
    } 
} 

및 사용 예 : 당신이 그것으로 완료 될 때까지

char buffer[256]; 
int num1, num2; 

readLine(newsockfd, buffer); 
num1 = atoi(buffer); 
readLine(newsockfd, buffer); 
num2 = atoi(buffer); 
1

먼저 for 루프 앞에 connection() 함수를두고 close() 함수를 추가하십시오.

당신이 무엇
n = read (newsockfd, buffer, 255); 

, 한 번 읽어 실시합니다, 그리고 데이터를 완전히 사용하지 못할 수 있습니다 : 그냥 생각이 여기에

connect (sockfd, (struct sockaddr *) &serv_addr, sizeof (serv_addr) 
for (i=0;i<n;i++){ 
// do you introspection with server 
// actually send number to server 
} 
// Code to read result: SUM from server 
close (sockfd); 
+0

나는 잘 했어, 그리고 클라이언트 측에서 연결을 거부했다 – Juraj

+0

@Juraj 연결하기 전에() 당신은 주소 준비 번호가 당신이 루프를하기 전에 모두 바깥으로 이동해야 할 단계 –

+0

고마워, 내가 집에 가자 마자 그것을 시도 할 것입니다! – Juraj

관련 문제