[Question] Lập trình c trên Linux -- lỗi khi sử dụng hàm signal(SIGALRM,...) |
07/12/2009 23:43:42 (+0700) | #1 | 200049 |
|
netstart
Member
|
0 |
|
|
Joined: 06/12/2009 10:57:38
Messages: 7
Offline
|
|
Bài tập lập trình mạng (c trên linux) của bọn em tuần này là viết chương trình ngang hàng (một máy chạy vừa đóng vai trò làm client vừa là server).
Yêu cầu tối thiểu là tìm kiếm danh sách file trong thư mục /tmp/k51mmt/ ở các máy cùng chạy chương trình :
Chương trình của em viết dùng 1 thread để tạo 1 luồng mới luồng này mục đích là tạo truy vấn tìm kiếm file theo keyword
Thread chính thì tạo một socket udp để lắng nghe kết nối, tới, mỗi khi có một kết nối tới nó sẽ tạo một thread mới để xử lý yêu cầu của kết nối này.
Dưới đây là code chuơng trình của em :
Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
//typedef void Sigfunc (int);
int searchRequest();
void * search(void * arg) ;
void * doit(void * arg) ;
static void recvfrom_alarm(int signo);
struct paramenter{
struct sockaddr_in clientaddr ;
int fd ;
char * fileName ;
};
int main(){
//khoi tao socket udp
int fd ;
int nBytes ;
if((fd = socket(AF_INET,SOCK_DGRAM,0)) < 0){
perror("error when create socket") ;
exit(1) ;
}
// khai bao cau truc dia chi cua server , client
struct sockaddr_in serveraddr ;
struct sockaddr_in clientaddr ;
int len_sock_server = sizeof(serveraddr) ;
int len_sock_client = sizeof(clientaddr) ;
bzero(&serveraddr, len_sock_server) ;
serveraddr.sin_family = AF_INET ;
serveraddr.sin_port = htons(12345) ;
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
// lang nghe ket noi
if(bind(fd, (struct sockaddr*) &serveraddr,len_sock_server) < 0){
perror("could not open socket") ;
exit(1) ;
}
// tao thread de thuc hien thao tac yeu cau tim kiem file.
pthread_t tid ;
pthread_create(&tid,NULL,search,NULL) ;
// o luong chinh thuc hien viec lang nghe yeu cau tu cac may khac guoi toi.
char * fileName ;
fileName = (char*)malloc(25) ;
for(;;){
pthread_t newThread ;
nBytes = recvfrom(fd, fileName, 25, 0 ,(struct sockaddr*) &clientaddr, &len_sock_client);
if(nBytes < 0) {
perror("recvfrom");
break;
}
// gan gia tri cho cac thanh phan cua bien cau truc paramenter.
struct paramenter paramenters ;
paramenters.fd = fd ;
paramenters.fileName = (char*)malloc(25) ;
strcpy(paramenters.fileName,fileName) ;
paramenters.clientaddr = clientaddr ;
// tao thread xu li viec tra loi request tu cac may.
int t = pthread_create(&newThread,NULL,doit,(void *)¶menters) ;
if(t != 0){
perror("could not create new thread\n") ;
}
}
return 0 ;
}
//---------------------------------------------------------------------------------------------------
// ham doit xu ly viec tra loi request tu cac may guoi den.
void * doit(void * arg){
pthread_detach(pthread_self()) ;
int nbyte ;
long size = 0;
struct paramenter * assig ;
assig = (struct paramenter *)arg ;
char buff[100] = "ls /tmp/k51mmt/ |grep " ;
strcat(buff,assig->fileName) ;
char buff2[10] = " > newfile" ;
strcat(buff,buff2);
system(buff);
FILE * finput ;
finput = fopen("newfile", "r") ;
if(finput == NULL){
perror("Error when open new file") ;
return ;
}
fseek (finput, 0, SEEK_END);
size = ftell(finput);
if(size == 0){
//printf("khong co ket qua") ;
return ;
}
fseek (finput,0,SEEK_SET) ;
char * ch ;
ch = (char *) malloc(1500) ;
int n ;
n = fread(ch,sizeof(char),1500,finput) ;
if(n < 0){
printf("can't read file\n") ;
}
// guoi du lieu toi may da hoi.
nbyte = sendto((assig->fd),ch,n,0,(struct sockaddr*)&(assig->clientaddr),sizeof((assig->clientaddr))) ;
if(nbyte < 0){
perror("error when send data\n") ;
}
sleep(2) ;
close(assig->fd) ;
fclose(finput) ;
//system("rm -f newfile") ;
}
//---------------------------------------------------------------------------------------------------
// ham search phuc vu thao tac tim kiem.
void * search(void* arg){
pthread_detach(pthread_self()) ;
for(;;){
int number ;
number = searchRequest() ;
if(number == 0){
printf("Khong co server nao co ten file chua tu khoa da nhap vao \n") ;
printf("----------------------------------------------------------\n") ;
printf("Nhap 1 de tim kiem voi tu khoa khac \n") ;
printf("Nhap so bat ky (khac 1) de thoat \n") ;
fflush(stdin) ;
int c ;
scanf("%d",&c) ;
if(c == 1)
continue ;
else
exit(1) ;
}
else{
printf("Nhap 1 de tim kiem voi tu khoa khac \n") ;
printf("Nhap 2 de xem list file phu hop download file tu 1 server xac dinh\n") ;
printf("Nhap so bat ky (khac 1,2) de thoat \n") ;
fflush(stdin) ;
int c ;
scanf("%d",&c) ;
switch(c){
case 1 :
continue ;
case 2 :
//download() ;
printf("download here\n") ;
continue ;
default :
exit(1) ;
}
}
printf("--------------------------------------------------\n") ;
}
}
//---------------------------------------------------------------------------------------------------
static void recvfrom_alarm(int signo){
return;
}
//---------------------------------------------------------------------------------------------------
/* ham searchRequest dung de guoi, nhan truy van toi cac may khac.
ham nay tra lai gia tri int la so cac may tra loi truy van guoi di
dong thoi hien thi ip, chi tiet cac file thoa man tren cac may do
*/
int searchRequest(){
int result = 0;
int sockfd ;
int nBytes ;
int len;
struct sockaddr_in serveraddr ;
serveraddr.sin_family = AF_INET ;
serveraddr.sin_port = htons(12345) ;
serveraddr.sin_addr.s_addr = inet_addr("255.255.255.255");
char fileName[25] ;
if((sockfd = socket(AF_INET,SOCK_DGRAM,0)) < 0){
perror("error when create socket") ;
return ;
}
printf("Nhap ten file can tim kiem : \n") ;
scanf("%s",fileName);
const int on = 1 ;
setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) ;
// ham sysv_signal thay the ham signal
sysv_signal(SIGALRM, recvfrom_alarm);
nBytes = sendto(sockfd, fileName, strlen(fileName), 0,(struct sockaddr*) &serveraddr , sizeof(serveraddr));
alarm(5) ;
for(;;){
struct sockaddr_in preply_addr ;
len = sizeof(preply_addr) ;
char * recvString ;
recvString = (char*)malloc(1500) ;
int n ;
n = recvfrom(sockfd, recvString, 1500, 0, (struct sockaddr*)&preply_addr, &len);
if(n < 0){
if (errno == EINTR){
printf("loi j cung phai noi 1 cau chu \n") ;
break;
}
else
continue;
}
char out[128];
const char *str;
str = (char*)malloc(50) ;
str = inet_ntoa(preply_addr.sin_addr) ;
printf("from %s :\n %s \n",str,recvString) ;
result ++ ;
//str = inet_ntop(AF_INET, &(((struct sockaddr_in *)preply_addr)->sin_addr), out, sizeof(out));
//printf("from %s: %s \n",out, recvString);
}
close(sockfd);
return result ;
}
kết quả chạy lại báo cái thông báo : recvfrom: Interrupted system call
là do khi tín hiệu SIGALRM gưởi tới thì hàm recvfrom (n = recvfrom(sockfd, recvString, 1500, 0, (struct sockaddr*)&preply_addr, &len); ... trong hàm search()) bị ngắt, bình thường thì nó không sao, bữa nay nó lại bị lỗi này. Em fix mãi không được
Anh chị, bạn nào có thể giúp em fix lỗi được không
em đính kèm theo tệp code của em nếu ai rảnh thì xem hộ em cái ạ
Cảm ơn mọi người ! |
|
|
|
|
[Question] Lập trình c trên Linux -- lỗi khi sử dụng hàm signal(SIGALRM,...) |
09/12/2009 10:48:29 (+0700) | #2 | 200155 |
|
netstart
Member
|
0 |
|
|
Joined: 06/12/2009 10:57:38
Messages: 7
Offline
|
|
Sorry mọi người.
em đang mở 2 socket ở thread chính và thread phụ mà lại cùng lắng nghe.
Nên khi có SIGALRM thì bị ngắt mà em chỉ xử lý ở thread phụ. Lỗi là do thread chính bị ngắt đưa ra.
Sorry vì đã làm phiền mọi người, em cảm ơn |
|
|
Users currently in here |
1 Anonymous
|
|
Powered by JForum - Extended by HVAOnline
hvaonline.net | hvaforum.net | hvazone.net | hvanews.net | vnhacker.org
1999 - 2013 ©
v2012|0504|218|
|
|