![](/img/trans.png)
[英]result of child process's exection of some system command can't send to the father process with pipe
[英]UDP Server child process can't send
我正在嘗試使用UDP創建聊天程序。 我已經在客戶端和服務器中創建了父進程和子進程,以分別接收和發送消息。 問題是服務器無法發送。 請幫助。 這是我的代碼。
客戶
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <sys/stat.h>
#include <arpa/inet.h>
int main(int argc, char **argv)
{
int sockfd;
struct sockaddr_in servaddr;
socklen_t len = sizeof(servaddr);
char mesg[1024], rmesg[1024];
pid_t pid;
if(argc!=2){
printf("Usage: %s <ip_addr>\n",argv[0]);
exit(1);
}
sockfd = socket(PF_INET,SOCK_DGRAM,0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(54321);
inet_pton(AF_INET,argv[1],&servaddr.sin_addr);
pid = fork();
if(pid == 0) {
printf("Type 'exit' to Exit. \n");
while(1){
fgets(mesg,sizeof(mesg),stdin);
sendto(sockfd,mesg,strlen(mesg),0,(const struct sockaddr *)&servaddr,len);
if(strcmp(mesg, "exit\n") == 0)
break;
}
close(sockfd);
kill(pid, SIGINT);
exit(0);
}else{
while(1){
memset(rmesg,0,sizeof(rmesg));
if(recv(sockfd,rmesg,sizeof(rmesg),0) > 0 ){
printf("From Server: %s", rmesg);
}
}
}
close(sockfd);
return 0;
}
服務器
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <sys/stat.h>
#include <arpa/inet.h>
int main(int argc, char **argv)
{
int sockfd1;
struct sockaddr_in servaddr,cliaddr;
socklen_t len = sizeof(cliaddr);
char cli_ip[32];
char mesg[1024], smesg[1024];
pid_t pid1;
sockfd1 = socket(PF_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(54321);
inet_ntop(AF_INET,(struct in_addr *) &cliaddr.sin_addr, cli_ip, sizeof(cli_ip) );
if ( bind( sockfd1, (struct sockaddr*) &servaddr, sizeof(servaddr) ) < 0 ){
perror(NULL);
exit(-1);
}
pid1 = fork();
if(pid1 == 0){
while(1){
memset(mesg,0,sizeof(mesg));
if( recvfrom(sockfd1,mesg,sizeof(mesg),0,(struct sockaddr *)&cliaddr,&len) > 0 ){
printf("From client: %s",mesg);
}
}
}else{
printf("Type 'exit' to Exit. \n");
while(1){
fgets(smesg,sizeof(smesg),stdin);
sendto(sockfd1,smesg,strlen(smesg),0,(struct sockaddr *)&cliaddr,len);
if(strcmp(smesg, "exit\n") == 0)
break;
}
close(sockfd1);
kill(pid1, SIGINT);
exit(0);
}
return 0;
}
該問題最有可能出現在客戶端中:
while(1){ if(recv(sockfd,rmesg,sizeof(rmesg),0) > 0 ){ printf("From Server: %s", rmesg); } }
您正在未連接的套接字上調用recv
。 您可能會遇到一個忽略的錯誤(可能是ENOTCONN
)。 而且我相信您還會看到客戶端上的CPU使用率很高,因為它不斷循環,導致每個系統調用失敗。
解決方案是改用recvfrom
。 或者,即使套接字是SOCK_DGRAM
,也可以在套接字上調用connect
,但是通常不這樣做。
為什么在服務器和客戶端上使用相同的套接字? 這根本不符合邏輯。 一個更簡單的選擇是使用兩個線程。 一個線程處理服務器套接字,另一個線程處理客戶端線程。 當然,您還需要有兩個套接字-一個用於服務器,一個用於客戶端。 同樣,sendto()需要具有接收方的地址和端口信息。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.