【问题标题】:Socket Programming TCP . Server programming looping continuously套接字编程 TCP 。服务器编程不断循环
【发布时间】:2015-05-14 12:51:30
【问题描述】:

下面是 server.c 程序。当我将客户端连接到服务器时,服务器开始在接收消息部分无限循环

Server.c

#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>

int main()
{
    int sid,sid1,bin,lis,n,p,port, pid;
    struct sockaddr_in sin,c;
    socklen_t len;
    char buffer[40]="";
    char buffer1[20]="";
    char ip[30]="192.168.65.241";
    // printf("\nEnter the IP Address :");
    // scanf("%s",ip);
    printf("\nEnter the Port no.:");
    scanf("%d",&port);
    sid=socket(AF_INET,SOCK_STREAM,0);//END POINT CONN,
    if(sid<0)
    {
            perror("Socket : ");
            exit(0);
    }
    printf("\nSocket created successfully...");
    sin.sin_family=AF_INET;
    sin.sin_port=htons(port);
    inet_aton(ip,&sin.sin_addr);//SERVER ADDRESS
    bin=bind(sid,(struct sockaddr*)&sin,sizeof(sin));//BIND ADDRESS WITH SOCKET
    if(bin<0)
    {
            perror("\nBind : ");
            exit(0);
    }
    printf("\nBinding has been done successfully...");
    lis=listen(sid,10);//LISTEN TO THE CLIENT
    if(lis<0)
    {
            perror("\nListen : ");
            exit(0);
    }
    len=sizeof(c);

     while(1){

        printf("A Client is connected to the server.....");
        sid1=accept(sid,(struct sockaddr*)&sin,&len);//ACCEPT CONN.FROM CLIENT
        if(sid1<1)
        {
            perror("\nAccept : ");
            exit(0);
        }
        pid=fork();//CREATE PARENT AND CHILD PROCESS

        if(pid<0){

            perror("ERROR on fork");
            exit(1);
        }
        if(pid==0){

            lis=listen(sid,10);
            printf("\nEnter message...(Type END to terminate):\n");
            scanf("%s",buffer);
            while(strcmp(buffer,"END")!=0)
            {
                send(sid,buffer,30,0);//SEND TO SERVER
                scanf("%s",buffer);
            }
            send(sid,"END",5,0);
            printf("\nTerminating the server...\n");
            exit(0);
        }
        else{

            n=recv(sid,buffer1,30,0);//RECEIVE FROM CLIENT
            buffer[n]='\0';
            n=strcmp(buffer1,"END");
            while(strcmp(buffer1,"END")!=0)
            {
                **printf("\nClient: %s\n",buffer1);** // Infinite Looping
                n=recv(sid,buffer1,30,0);
            }
            printf("\nA client has been disconnected from the server...\n");    
            exit(0);
        }
                            close(sid); //CLOSE CONNECTIONS
                                                                        close(sid1);    //CLOSE CONNECTIONS


     }
    shutdown(sid,2);    //SHUTDOWN READ AND WRITE
    close(sid); //CLOSE CONNECTIONS
}

Client.c

客户端程序没有问题。添加代码供您参考。

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <errno.h>
int main()
{
    int sid,bi,con,n,p,port;
    char buffer[50],ip[30];
    sid=socket(AF_INET,SOCK_STREAM,0);//END POINT CONN.
    if(sid==-1)
    {
            perror("\nSocket :");
        exit(0);
    }
    printf("A Socket created successfully....");
    struct sockaddr_in sin;
    sin.sin_family = AF_INET;
    printf("\nEnter the IP Address :");
    scanf("%s",ip);
    printf("\nEnter the Port no. :");
    scanf("%d",&port);
    sin.sin_port = htons(port);
    inet_aton(ip,&sin.sin_addr);
    con=connect(sid,(struct sockaddr*)&sin,sizeof(sin));//CONNECT TO SERVER
    if(con == -1)
    {
        perror("Connection : ");
            exit(0);
    }
    printf("\nConnection is successfull to the server(%s)....\n",ip);
    p=fork();
    if(p)
        {
            printf("\nEnter message...(Type END to terminate):\n");
            scanf("%s",buffer);
            while(strcmp(buffer,"END")!=0)
            {
                    send(sid,buffer,30,0);//SEND TO THE SERVER
                    scanf("%s",buffer);
            }
            send(sid,"END",4,0);
        printf("\nTerminating the client...\n");
        exit(0);
        }
        else
        {
                n=recv(sid,buffer,30,0);//RECV.FROM SERVER
        printf("%d",n);
        buffer[n+1]='\0';
            while(strcmp(buffer,"END")!=0)
            {
                    printf("\nServer: %s\n",buffer);
                    n=recv(sid,buffer,30,0);
            }
            send(sid,"END",4,0);
        exit(0);
        }
    printf("\nClient is terminated...\n");
    shutdown(sid,2);//SHUTDOWN READ AND WRITE
    close(sid); //CLOSE CONNECTIONS
}

请尽快告诉我解决方案。

【问题讨论】:

  • 首先开始检查错误,有些系统调用你没有检查。例如在子进程中,你为什么在服务器套接字上调用listen?该调用很可能会失败。

标签: c sockets unix network-programming


【解决方案1】:

您在调用server.c 的读/写时使用了错误的套接字。

目前,所有读取/写入调用都失败,errno 表示套接字未连接。

您应该使用sid1,连接的套接字,而不是sid

您还应该检查返回值,以便检测和处理错误。

【讨论】:

    【解决方案2】:

    主要问题,即无限循环仅仅是因为在服务器的主套接字 (sid) 上调用了 recv(),而不是 accept() - sid1 返回的套接字。改变这个:

    n=recv(sid,buffer1,30,0);//RECEIVE FROM CLIENT
    

    n=recv(sid1,buffer1,30,0);//RECEIVE FROM CLIENT
    

    n=recv(sid,buffer1,30,0);
    

    n=recv(sid1,buffer1,30,0);
    

    你会做生意的。

    服务器代码还有其他问题:

    1. recv() 被告知将最多 30 个字节读入 buffer1, 但是,buffer1 的大小只有 20 个字节 - 你有一个缓冲区 超越那里。
    2. 如果客户端关闭连接而不发送“END”并且 在接收循环中会发生无限循环。你需要检测 recv() 返回 0 表示的连接关闭。
    3. listen() 在第 64 行的服务器中被不必要地调用。

    以上列表可能并不详尽。

    【讨论】:

    • 无限循环已停止..但是由于我编写了一个多客户端接受服务器,所以它不会发生,直到我关闭当前客户端连接,它已准备好接受下一个客户端...什么这是解决方案吗?
    • 实际上,您似乎倒退了。您在 parent 而不是 child 中分叉和处理数据的接收。 fork() 向子进程返回 0,向父进程返回子进程的进程 ID。在这种情况下,您的接收代码调用exit() 终止父级。我不知道你想在子代码中做什么。
    猜你喜欢
    • 1970-01-01
    • 2011-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-25
    相关资源
    最近更新 更多