2013-07-05 40 views
-1

我想实现Socket,其中客户端发送句子到服务器和服务器回复两个整数瓦特pcount和ncount。我可以收到这两个,但第一个recv操作接收这两个值,并附加一些其他数据缓冲区。在TCP套接字编程中执行顺序的发送和接收操作

Client.cpp

#include <fcntl.h> 
    #include <string.h> 
    #include <stdlib.h> 
    #include <errno.h> 
    #include <stdio.h> 
    #include <netinet/in.h> 
    #include <resolv.h> 
    #include <sys/socket.h> 
    #include <arpa/inet.h> 
    #include <unistd.h> 

    char *foo(char* buf) 
    { 
     char buffer[1024]; 
     char *a='\0'; 
     char *c=buf; 
     strcpy(buffer,buf); 

     int host_port= 1102; 
     char* host_name="127.0.0.1"; 

     struct sockaddr_in my_addr; 

     //char buffer[1024]; 
     int bytecount; 
     int buffer_len=0; 

     int hsock; 
     int * p_int; 
     int err; 

     hsock = socket(AF_INET, SOCK_STREAM, 0); 
     if(hsock == -1){ 
      printf("Error initializing socket %d\n",errno); 
      goto FINISH; 
     } 

     p_int = (int*)malloc(sizeof(int)); 
     *p_int = 1; 

     if((setsockopt(hsock, SOL_SOCKET, SO_REUSEADDR, (char*)p_int, sizeof(int)) == -1)|| 
      (setsockopt(hsock, SOL_SOCKET, SO_KEEPALIVE, (char*)p_int, sizeof(int)) == -1)){ 
      printf("Error setting options %d\n",errno); 
      free(p_int); 
      goto FINISH; 
     } 
     free(p_int); 

     my_addr.sin_family = AF_INET ; 
     my_addr.sin_port = htons(host_port); 

     memset(&(my_addr.sin_zero), 0, 8); 
     my_addr.sin_addr.s_addr = inet_addr(host_name); 

     if(connect(hsock, (struct sockaddr*)&my_addr, sizeof(my_addr)) == -1){ 
      if((err = errno) != EINPROGRESS){ 
       fprintf(stderr, "Error connecting socket %d\n", errno); 
       goto FINISH; 
      } 
     } 

     //Now lets do the client related stuff 

     buffer_len = 1024; 
     memset(buf, '\0', buffer_len); 

     buf[strlen(buf)-1]='\0'; 

     if((bytecount=send(hsock, buffer, strlen(buffer),0))== -1){ 
      fprintf(stderr, "Error sending data %d\n", errno); 
      go 

    to FINISH; 
      } 
      printf("Sent bytes %d\n", bytecount); 
     //------- 


    // may Needs to empty content of buffer here but dont know how to do. Tried with fflush, free(buffer) but does not work 

//Two recv function which ideally recv pcount and ncount subsequently 

      if((bytecount = recv(hsock, buffer, buffer_len, 0))== -1){ 
       fprintf(stderr, "Error receiving data %d\n", errno); 
       goto FINISH; 
      } 
      printf("Recieved bytes %d\nReceived string \"%s \n", bytecount, buffer); 

    //Needs to empty content of buffer here but dont know how to do. Tried with fflush, free(buffer) but does not work 

if((bytecount = recv(hsock, buffer, buffer_len, 0))== -1){ 
      fprintf(stderr, "Error receiving data %d\n", errno); 
      goto FINISH; 
     } 
     printf("Recieved bytes %d\nReceived string \"%s \n", bytecount, buffer); 




     close(hsock); 

    FINISH: 
    ; 

    return buffer; 
    } 

而且server.cpp:

#include <fcntl.h> 
    #include <string.h> 
    #include <stdlib.h> 
    #include <errno.h> 
    #include <stdio.h> 
    #include <netinet/in.h> 
    #include <resolv.h> 
    #include <sys/socket.h> 
    #include <arpa/inet.h> 
    #include <fcntl.h> 
    #include <string.h> 
    #include <stdlib.h> 
    //#include <errno.h> 
    #include <stdio.h> 
    #include <netinet/in.h> 
    #include <resolv.h> 
    #include <sys/socket.h> 
    #include <unistd.h> 
    //#include <sstream.h> 
    #include <pthread.h>       
    #include "serverFunction.cpp" 
    #include "serverFunction2.cpp" 
    #include <iostream> 
    #include <sstream> 
    #include <cstdio> 
    using namespace std; 
    void *SocketHandler(void *); 

    int main(int argv, char **argc) 
    { 
     int host_port = 1102; 
     char buf[20]; 
     int k; 
     struct sockaddr_in my_addr; 

     int hsock; 
     int *p_int; 
     int err; 

     socklen_t addr_size = 0; 
     int *csock; 
     sockaddr_in sadr; 
     pthread_t thread_id = 0; 


     hsock = socket(AF_INET, SOCK_STREAM, 0); 
     if (hsock == -1) { 
     printf("Error initializing socket %dn", errno); 
     goto FINISH; 
     } 

     p_int = (int *) malloc(sizeof(int)); 
     *p_int = 1; 

     if ((setsockopt(hsock, SOL_SOCKET, SO_REUSEADDR, (char *) p_int, sizeof(int)) == -1) || (setsockopt(hsock, SOL_SOCKET, SO_KEEPALIVE, (char *) p_int, sizeof(int)) == -1)) { 
     printf("Error setting options %dn", errno); 
     free(p_int); 
     goto FINISH; 
     } 
     free(p_int); 

     my_addr.sin_family = AF_INET; 
     my_addr.sin_port = htons(host_port); 

     memset(&(my_addr.sin_zero), 0, 8); 
     my_addr.sin_addr.s_addr = INADDR_ANY; 

     if (bind(hsock, (sockaddr *) & my_addr, sizeof(my_addr)) == -1) { 
     fprintf(stderr, "Error binding to socket, make sure nothing else is listening on this port %dn", errno); 
     goto FINISH; 
     } 
     if (listen(hsock, 10) == -1) { 
     fprintf(stderr, "Error listening %dn", errno); 
     goto FINISH; 
     } 
     //Now lets do the server stuff 

     addr_size = sizeof(sockaddr_in); 

     while (true) { 
     printf("waiting for a connectionn\n"); 
     csock = (int *) malloc(sizeof(int)); 
     if ((*csock = accept(hsock, (sockaddr *) & sadr, &addr_size)) != -1) { 
      printf("---------------------nReceived connection from %s\n", inet_ntoa(sadr.sin_addr)); 
      pthread_create(&thread_id, 0, &SocketHandler, (void *) csock); 
      pthread_detach(thread_id); 
     } else { 
      fprintf(stderr, "Error accepting %dn", errno); 
     } 
     } 

     FINISH: 
     ; 
    } 

    void *SocketHandler(void *lp) 
    { 

     int result=0; 
     //std::stringstream ss; 
     int *csock = (int *) lp; 
     char buf[20]; 
     int k; 
    // char *target="my name is khan"; 
     char *str; 
     char *str2; 
     int pcount = 0, ncount = 0; 

     char buffer[1024]; 
     int buffer_len = 1024; 
     int bytecount; 

     int i = 0,t=0,q=0; 
     int j = 0; 
     char *ch[50] = { 0 }; /* stores references to 50 words. */ 
     char *ch2[50] = { 0 }; 

     char *word = strtok(buffer, " "); 
     char *word2 = strtok(buffer, " "); 

     char *portstring1=(char *)malloc(sizeof(buffer)); 
     char *portstring2=(char *)malloc(sizeof(buffer)); 

     memset(buffer, 0, buffer_len); 
     if ((bytecount = recv(*csock, buffer, buffer_len, 0)) == -1) { 
     fprintf(stderr, "Error receiving data %d \n", errno); 
     goto FINISH; 
     } 
     printf("Received bytes %d \n Received string %s \n ", bytecount, buffer); 
     /* stores references to 50 words. */ 
     word = strtok(buffer, " "); 

     while ((NULL != word) && (50 > i)) { 
     ch[i] = strdup(word); 
     //printf("%s n", ch[i]); 

     str = BoyerMoore_positive(ch[i], strlen(ch[i]) - 1); 
     str2= BoyerMoore_negative(ch[i], strlen(ch[i]) - 1); 
     if (str == NULL) 
      t++; 
     else { 
       printf("%s \n", ch[i]); 
      // puts("true"); 
      pcount += 1; 
      printf("Positive count is: %d \n",pcount); 
     } 

     if(str2== NULL) 
      q++; 
     else { 
       printf("%s \n", ch[i]); 
      // puts("true"); 
      ncount += 1; 
      printf("Nagative count is: %d \n",ncount); 
     } 

     i++; 
     word = strtok(NULL, " "); 
     } 

//I want to send pcount and ncount values to client 

     **sprintf(portstring1, "%d", pcount); 

     if ((bytecount = send(*csock, portstring1, 1, 0)) == -1) { 
     fprintf(stderr, "Error sending data %d\n", errno); 
     goto FINISH; 
     } 

     sprintf(portstring2, "%d", ncount); 

      if ((bytecount = send(*csock, portstring2, strlen(portstring2), 0)) == -1) { 
     fprintf(stderr, "Error sending data %d\n", errno); 
     goto FINISH; 
     }** 

     FINISH: 
     free(csock); 
     return 0; 
    } 

我收到输出是这样的:

Enter sentence to send to the server (press enter) 
critic worst nice 
Sent bytes 18 
Recieved bytes 2 
Received string 12itic worst nice //Here there should be only 1 2. Why 'itic ..' gets appended. And why 1 and 2 both does not get printed one after another 
+0

它不'追加一些其他数据到缓冲区'。垃圾已经在那里。 – EJP

回答

0

@Joni和David-感谢您的支持!

问题解决了:

在发件人:

int ar[2]; 

if ((bytecount = send(*csock, (char *)ar, 2 *sizeof(int), 0)) == -1) { // Here we cant send lenth-1. It consider exact 
    fprintf(stderr, "Error sending data %d\n", errno); 
    goto FINISH; 
    } 

在接收端:

if((bytecount = recv(hsock, ar, 2 * sizeof(int), 0))== -1){ 
     fprintf(stderr, "Error receiving data %d\n", errno); 
     goto FINISH; 
    } 


    for(k=0;k<2;k++) 
    { 
     printf("count is :%d",ar[k]); 
    } 

只是把和数组,现在我可以发送任何接收值的任何数字!它是如此容易!

1

recv函数不添加空字符终止收到的字符串。您必须自己添加它,如下所示:

if((bytecount = recv(hsock, buffer, buffer_len-1, 0))== -1){ 
      fprintf(stderr, "Error receiving data %d\n", errno); 
      goto FINISH; 
} 
buffer[bytecount]=0; 

请注意缓冲区len中的-1,以确保nul字符有空间。

+0

是的,我做到了,它使改善。当我把“memset(buffer,0,1024);”在第一次recv()之后,它首先从服务器接收到第一次发送的值。但不显示从服务器发送的第二个计数值!在第一次recv()之后,我把“memset(buffer,0,1024);”然后recv(),在这种情况下,它会进入不断的监听模式! – user123

+0

如果你想第一次调用recv只读一个字符,你应该传递1而不是buffer_len到recv。 – Joni

+0

我将recv的值的大小可能会改变。那么我怎么可以让它变硬呢?是否有可能首先发送我想发送的邮件的大小,然后recv()只有多少?但在这种情况下,问题可能是数据类型。在套接字中,我只能发送char *,而不是int值! – user123

1

你忘了设计和实现一个协议。网络通信不起作用。如果您有应用程序级消息的概念,则必须编写代码来发送和接收应用程序级消息。你没有这样做,所以当然不会发生。

另外:

printf("Received bytes %d \n Received string %s \n ", bytecount, buffer); 

%s格式说明仅用于C风格的字符串。它不适合任意数据。它如何知道要打印多少个字节?

+0

这是关于原始问题的主题,请问您可以告诉我如何为应用程序级别的消息发送和rec代码? – user123

+0

查看具有SMTP,HTTP,IRC等应用程序级别消息的其他协议的规范。您必须定义消息是什么以及如何标记消息,然后编写代码来识别消息边界。 –

+0

我GOOGLE了,但无法找到与我的东西相关。你能告诉我究竟应该搜索什么? – user123

相关问题