-1

我正在尝试实现客户端向服务器发送句子和服务器回复两个整数 valeus pcount 和 ncount 的 Socket。我可以同时接收这两个值,但第一个 recv 操作会接收这两个值并将一些其他数据附加到缓冲区。

客户端.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
4

3 回答 3

1

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

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 字符有空间。

于 2013-07-05T08:09:34.360 回答
1

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

还:

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

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

于 2013-07-05T08:10:01.487 回答
0

@Joni 和大卫-感谢您的支持!

问题解决了:

在发件人处:

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]);
    }

刚刚拿了数组,现在我可以发送任何接收任意数量的值了!它是如此容易!

于 2013-07-05T17:34:19.403 回答