编写处理TCP和UDP服务器的服务器时出现问题

时间:2015-04-11 06:34:12

标签: c sockets unix tcp udp

我正在编写一个服务器程序作为处理TCP和UDP客户端的赋值的一部分。我是用select函数写的。我的TCP服务器很棒,但我的UDP服务器工作不正常。

我的每个服务器逻辑的第一行是"正确到达UDP / TCP服务器部分" TCP服务器中的行正确打印但不是UDP部分。

该程序的主要目的是给一个书名,我将在文件中搜索并显示authorname。我必须处理tcp和udp部分。提前谢谢。

 int main(int argc, char **argv)
{
char *line=(char*)malloc(sizeof(char)* MAXLINE); //line contains each line from the books.d file 
char *line_camel=(char*)malloc(sizeof(char) * MAXLINE); //allocating memory for the charecter pointers
char *title=(char*)malloc(sizeof(char) * MAXLINE);//allocating memory to hold the title from read from the client
char *search= (char*)malloc(sizeof(char) * MAXLINE);//allocating memory to store the search string 
char *temp=(char*)malloc(sizeof(char) * MAXLINE);
char authorname[MAXLINE]= "No Book\n";
authorname[7]='\n';
char *noresult="No Book\n"; //pointer to a charecter array
char semicolon=':';
int port; //used to store the port number
int listenfd; //listen fd for the socket address structure
int udpfd;
int connfd; //connfd
int maxfdp1;    
int nready;
socklen_t len;
fd_set rset;
FILE *fp; //File pointer 
int n;
int end;
pid_t childpid; //for fork system call
struct sockaddr_in servaddr, cliaddr; //declaring the socket address structure
if(argc != 2)// if the user has not given a port address through the parameters
{
    port = SERV_PORT; //assign the default port address
}
else
{
    port = atoi(argv[1]); //assign the user entered port number
}

listenfd = Socket(AF_INET, SOCK_STREAM, 0); //The server accepts the connections from the client
bzero(&servaddr, sizeof(servaddr));//clearing the contents of the socket address structure
servaddr.sin_family = AF_INET;//assigning IPV4 as the family for the socket address structure
servaddr.sin_port = htons(port); //converting from host to network order
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

Bind(listenfd, (SA *) &servaddr, sizeof(servaddr)); //binding the socket address structure
Listen(listenfd, LISTENQ);//specifying the maximum backlog connections

udpfd = Socket(AF_INET, SOCK_DGRAM, 0);
bzero ( &servaddr, sizeof ( servaddr ) );
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl ( INADDR_ANY );
servaddr.sin_port = htons( port );

Bind(udpfd, (SA *) &servaddr, sizeof(servaddr) );

signal(SIGCHLD, sig_chld);
FD_ZERO ( &rset );
maxfdp1 = max ( listenfd, udpfd ) + 1;

fp = fopen("/home/631/common/books.d", "r");
while(true)
{
    FD_SET ( listenfd, &rset ); 
    FD_SET ( udpfd, &rset );

    if ( ( nready = select ( maxfdp1, &rset, 0, 0, 0 ) ) < 0 )
        continue;

    if ( FD_ISSET ( listenfd, &rset ) ) 
    {
        printf("Correctly reached the tcp part of the server\n");
        len = sizeof ( cliaddr ); 
        for(; ;)
        {
        errno = 0;
        connfd = Accept(listenfd, NULL, NULL);      
        if(errno == EINTR)
            continue;
        else
            break;
        }
        if ( ( childpid = Fork ( ) ) == 0 ) 
        {
                Close ( listenfd );
                while((n = Readline(connfd, title, MAXLINE)) > 0)
                {
                    title[n-1] = '\0';//explicitly putting a '\0' at the end of the input query to make it a  c-string
                    title=convert_tolower(title);//convert to lower case and catching it back
                    while( Fgets(line, MAXLINE, fp) != NULL )// reading each line from the server
                    {
                        string_copy(line_camel, line); //copying the line read to another line for result 
                        line=convert_tolower(line);//convert the line to lowercase
                        search= strstr(line, title); //checking if there is a substring with title (bookname) in the line
                        if( search != NULL && search[strlen(title)] == semicolon)
                        {                          
                        temp = strchr(line_camel, semicolon); //retrieving the substring from the earlier stored line 
                        end= strlen(temp); //always the last but one and the last by one plus one indices are '\0' and '\n'
                        temp[end-2] = '\n';// this place has : but we need to over write it with \n if we want to transfer
                        temp[end-2+1] ='\0';//mark the end of the string
                        ++temp;// *(temp) has : but we want to skip that charecter. if we dereference temp, we have ':'
                        string_copy(authorname, temp);//copying to author
                        //authorname[strlen(authorname)] = '\n'; //mark a '\n' charecter to transmit to the client
                        }
                    }      
                    end=strlen(authorname);
                    Writen(connfd, authorname, strlen(authorname));//wrting the saved authorname to the socket 
                    string_copy(authorname,noresult);//resetting it back 
                    authorname[7]='\n';
                    rewind(fp);//rewind the file pointer to the start of the file
                }       
                Close ( connfd ); 
                exit ( 0 );
        }
        Close ( connfd );
    }
    if ( FD_ISSET ( udpfd, &rset ) ) 
    {
        printf("Correctly reached the udp part of the server ");
        len = sizeof ( cliaddr );
        n = recvfrom ( udpfd, title , MAXLINE, 0, NULL, NULL);
        sendto( udpfd, title, strlen(title), 0, ( SA* ) &cliaddr, len );
        rewind(fp);//rewind the file pointer to the start of the file
    }
}
Close(listenfd);
Fclose(fp);
exit(0);
}

1 个答案:

答案 0 :(得分:1)

我试过你的代码。有效。 (当然,只是TCP / UDP部分。休息评论出来):

  

正确到达服务器的udp部分
  正确地达到了   tcp服务器的一部分

很少有建议:

在客户端和服务器端捕获tcpdump。检查痕迹。

UDP客户端是否真的发送了数据包?

正如WalterA在评论中所建议的那样,在printf中有\n