我正在编写一个服务器程序作为处理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);
}
答案 0 :(得分:1)
我试过你的代码。有效。 (当然,只是TCP / UDP部分。休息评论出来):
正确到达服务器的udp部分
正确地达到了 tcp服务器的一部分
很少有建议:
在客户端和服务器端捕获tcpdump
。检查痕迹。
UDP客户端是否真的发送了数据包?
正如WalterA在评论中所建议的那样,在printf中有\n