[英]How do i fix my pipe in linux socket program?
我包含了我的一些代码,当我运行我的程序(服务器)时,一切正常,除了 pipe 我真的不确定问题出在哪里,output 总是打印 0 并且两个错误消息都被打印出来。(点代表块我省略了代码)首先程序与客户端建立连接,然后开始通信,在通信结束时子进程中的 pipe 假设将变量小时发送到父进程中的 pipe。
#define PORT 4444
#define BUF_SIZE 2000
#define CLADDR_LEN 100
void func(int subor,int rychlost,int *h,int *m,int *s){
int hours,minutes,seconds,inputSecond;
int remainingSeconds;
int secondsInHour = 60 * 60;
int secondsInMinute = 60;
subor *= 8000;
rychlost *= 1000;
inputSecond = subor/rychlost;
hours = (inputSecond/secondsInHour);
remainingSeconds = inputSecond - (hours * secondsInHour);
minutes = remainingSeconds/secondsInMinute;
remainingSeconds = remainingSeconds - (minutes*secondsInMinute);
seconds = remainingSeconds;
*h=hours;
*m=minutes;
*s=seconds;
}
void main() {
struct sockaddr_in addr, cl_addr;
int sockfd, len, ret, newsockfd,fileSize,speed;
char buffer[BUF_SIZE]="Type 'start' or 'exit'\n";
pid_t childpid;
int hours,minutes,seconds;
int fd[2];
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
printf("Error creating socket!\n");
exit(1);
}
printf("Socket created...\n");
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = PORT;
ret = bind(sockfd, (struct sockaddr *) &addr, sizeof(addr));
if (ret < 0) {
printf("Error binding!\n");
exit(1);
}
printf("Binding done...\n");
printf("Waiting for a connection...\n");
listen(sockfd, 5);
for (;;) {
len = sizeof(cl_addr);
newsockfd = accept(sockfd, (struct sockaddr *) &cl_addr, &len);
if (newsockfd < 0) {
printf("Error accepting connection!\n");
exit(1);
}
printf("Connection accepted...\n");
if ((childpid = fork()) == 0) {
close(fd[0]);
close(sockfd);
ret = send(newsockfd, buffer, BUF_SIZE, 0);
if (ret < 0) {
printf("Error sending data!\n");
exit(1);
}
for (;;) {
memset(buffer, 0, BUF_SIZE);
ret = recv(newsockfd, buffer, BUF_SIZE, 0);
if(ret < 0) {
printf("Error receiving data!\n");
exit(1);
}
if (strcmp(buffer, "start\n") == 0) {
ret = send(newsockfd, "Type size of file in [Mb]\n", BUF_SIZE, 0);
if (ret < 0) {
printf("Error sending data!\n");
exit(1);
}
ret = recv(newsockfd, buffer, BUF_SIZE, 0);
if(ret < 0) {
printf("Error receiving data!\n");
exit(1);
}
fileSize = atoi(buffer);
ret = send(newsockfd, "Type Speed of internet in [MB]\n", BUF_SIZE, 0);
if (ret < 0) {
printf("Error sending data!\n");
exit(1);
}
ret = recv(newsockfd, buffer, BUF_SIZE, 0);
if(ret < 0) {
printf("Error receiving data!\n");
exit(1);
}
speed = atoi(buffer);
func(fileSize,speed,&hours,&minutes,&seconds);
buffer[BUF_SIZE] = sprintf(buffer,"Upload bude trvat %d:%d:%d\n",hours,minutes,seconds);
if((write(fd[1], &hours,sizeof(int))) == -1){ \\problem is here
printf("write error\n");
}
close(fd[1]);
ret = send(newsockfd, buffer, BUF_SIZE, 0);
if (ret < 0) {
printf("Error sending data!\n");
exit(1);
}
exit(0);
}
}
}else{
wait();
close(fd[1]);
int fin;
if((read(fd[0], &fin, sizeof(int))) == -1){ \\problem is here
printf("read error\n");
}
printf("%d\n",fin);
close(fd[0]);
}
close(newsockfd);
}
}
好吧,在解决了您发送的代码中的一些问题之后,我想我已经让您的代码运行了:
$ netstat -p -l | grep pru28763
tcp 0 0 0.0.0.0:23569 0.0.0.0:* ESCUCHAR 46607/pru28763
$ _
您的进程实际上正在侦听,但不在端口4444
中,而是在端口46607
中。 这意味着您没有通过调用htons()
宏将端口号转换为网络字节顺序。 你需要这样做。
我将向您发送一个包含对您的代码所做的所有更正的差异,以使其运行,但您没有初始化数组fd[]
并且,因为我不知道您想如何使用它(没有在您发布的代码中调用pipe(2)
)我无法进一步帮助您:
diff --git a/pru28763.c b/pru28763.c
index 78792e9..a6b7c7d 100644
--- a/pru28763.c
+++ b/pru28763.c
@@ -57,7 +57,7 @@ void main() {
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
- addr.sin_port = PORT;
+ addr.sin_port = htons(PORT);
ret = bind(sockfd, (struct sockaddr *) &addr, sizeof(addr));
if (ret < 0) {
@@ -84,7 +84,7 @@ void main() {
close(sockfd);
- ret = send(newsockfd, buffer, BUF_SIZE, 0);
+ ret = send(newsockfd, buffer, strlen(buffer), 0);
if (ret < 0) {
printf("Error sending data!\n");
exit(1);
@@ -102,25 +102,32 @@ void main() {
}
- if (strcmp(buffer, "start\n") == 0) {
+ char *startmsg = "start\n";
+ if (strncmp(buffer, startmsg, strlen(startmsg)) == 0) {
- ret = send(newsockfd, "Type size of file in [Mb]\n", BUF_SIZE, 0);
+ char *msg = "Type size of file in [Mb]\n";
+ ret = send(newsockfd, msg, strlen(msg), 0);
if (ret < 0) {
printf("Error sending data!\n");
exit(1);
}
- ret = recv(newsockfd, buffer, BUF_SIZE, 0);
+ /* to allow for a \0 that must be put at the end of what
+ * is received */
+ ret = recv(newsockfd, buffer, BUF_SIZE - 1, 0);
if(ret < 0) {
printf("Error receiving data!\n");
exit(1);
}
+
+ buffer[ret] = '\0';
fileSize = atoi(buffer);
- ret = send(newsockfd, "Type Speed of internet in [MB]\n",
-BUF_SIZE, 0);
+ msg = "Type Speed of internet in [MB]\n";
+
+ ret = send(newsockfd, msg, strlen(msg), 0);
if (ret < 0) {
printf("Error sending data!\n");
exit(1);
@@ -131,6 +138,10 @@ BUF_SIZE, 0);
printf("Error receiving data!\n");
exit(1);
}
+
+ /* again, you must end a buffer read with a \0 if you
+ * want it to be checked with string routines */
+ buffer[ret] = '\0';
speed = atoi(buffer);
@@ -139,6 +150,7 @@ BUF_SIZE, 0);
buffer[BUF_SIZE] = sprintf(buffer,"Upload bude trvat %d:%d:%d\n",hours,minutes,seconds);
+ /* fd array has not been initialized, no pipe(2) call shown */
if((write(fd[1], &hours, sizeof(int))) == -1){ /*problem is here */
printf("write error\n");
}
@@ -162,6 +174,8 @@ BUF_SIZE, 0);
int fin;
+ /* no initialization of array fd, no pipe call shown in the snippet
+ * sent */
if((read(fd[0], &fin, sizeof(int))) == -1){ /*problem is here */
printf("read error\n");
}
顺便说一句,问题不在于您标记为候选人的任何一个地方,而是因为您坚持使用send(2)
发送文本消息而不指定数据长度,因此您发送完整的缓冲区,尽管内容可能有。 此外,您读取了一个完整的缓冲区,然后使用strcmp(3)
检查字符串。 客户端可以缓冲它的 output,并向您发送一个完整的 1500 字节数据块,以“start\n”开头,这将导致无法识别起始子序列。
我放弃了你的代码,它需要我花费一个多小时的时间,这不是我们都想要的。 我很抱歉。 尝试修复(并理解)我对您的代码所做的所有修改。 下一次,至少,将其格式化为至少可读。 缩进是理解程序逻辑的基础,你没有花足够的时间让阅读你的代码的人更容易理解。 请阅读如何创建一个最小的、可重现的示例以了解如何将代码发送到此论坛。
分叉子进程后,connect() 丢失。
您已使用newsockfd从子进程发送数据。 newsockfd是接受系统调用的返回值。 这是错误的。
阅读: https://www.geeksforgeeks.org/tcp-server-client-implementation-in-c/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.