LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 847|回复: 8

请问这个程序问题出在哪里,谢谢大家。

[复制链接]
发表于 2006-7-23 22:13:33 | 显示全部楼层 |阅读模式

  1. #include "myproxy.h"

  2. int
  3. main()
  4. {
  5.         int sockfd;
  6.         char ip[64];
  7.         char port[16];
  8.         struct sockaddr_in address;       
  9.         char request[256];
  10.         char response[256];
  11.         int ret;

  12.         /*input the ip address to test*/
  13.             printf("Pleae input the IP address:\n");
  14.         scanf("%s",ip);
  15.         printf("Pleae input the port:\n");
  16.         scanf("%s",port);       

  17.         /*create the socket*/
  18.          sockfd = socket(AF_INET, SOCK_STREAM, 0);
  19.         if(sockfd == -1)
  20.         {
  21.                 printf("Failed in creating socket!\n");
  22.         }

  23.         /*connect to the server by socket*/
  24.         address.sin_family = AF_INET;
  25.         address.sin_addr.s_addr = inet_addr(ip);
  26.         address.sin_port = htons(atoi(port));       
  27.         ret = connect(sockfd, (struct sockaddr *)&address, sizeof(address));
  28.         if(ret == -1)
  29.         {
  30.                 printf("Failed in connecting to server!\n");
  31.         }

  32.         /*send the http request*/
  33.         sprintf(request,
  34.                 "%s", "GET /index.html HTTP/1.1\r\n",
  35.                 //"%s", "Host:www.google.com\r\n",
  36.                 //"%s", "Connection:close\r\n",
  37.                 //"%s", "User-agent:Mozilla/4.0\r\n",
  38.                 "%s", "\r\n");
  39.         ret = strlen(request);
  40.         ret = write(sockfd, request, strlen(request));               
  41.         if(ret == -1)
  42.         {
  43.                 printf("Failed in writing data to socket!\n");
  44.         }

  45.         /*read the response from server*/
  46.         /*here i donnot check the integrity of the data*/
  47.         ret = 1;
  48.         //while(ret == 1)
  49.         {
  50.                 ret = read(sockfd, response, 256);
  51.         }
  52.         printf("%s", response);
  53.        
  54.         /*close the socket*/
  55.         close(sockfd);
  56. }
复制代码

===========================
为什么在read那里总会滞留住呢?是不是还要对socket设置些什么参数呢?
发表于 2006-7-24 14:53:59 | 显示全部楼层
如果以阻塞方式进行数据传输,那么假如对方没有数据发来,而又调用了read,那么就会被阻塞,也就是“滞留”了。

在read前用select或者poll判断一下是否有数据待读,或者是在read之前用alarm设置超时信号,或者是用一个单独的线程来read,或者干脆不要用阻塞型I/O就行了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-7-24 15:54:04 | 显示全部楼层
再问一下兄弟,如何改用非阻塞方式?谢谢。
回复 支持 反对

使用道具 举报

发表于 2006-7-24 17:15:41 | 显示全部楼层
  1. #include <fcntl.h>
  2. #include <stdio.h>
  3. #include <unistd.h>
  4. int setnonblock(int fd)
  5. {
  6.   int fdflags;
  7.   if ((fdflags = fcntl(fd, F_GETFL, 0)) == -1) return -1;
  8.   fdflags |= O_NONBLOCK;
  9.   if (fcntl(fd, F_SETFL, fdflags) == -1) return -1;
  10.   return 0;
  11. }
复制代码
以上是<UNIX System Programming>一书中的一段代码, 也许有用. 我自己向来都是用阻塞型I/O的, 用select作出判断. 这种方法的好处是便于同时监视多个文件描述符
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-7-24 17:34:01 | 显示全部楼层
谢谢兄弟的回复,不过我也觉得使用阻塞方式稍微方便一些,晚上回去把检测的过程放进一个线程里,可能就不会造成主过程的等待。
PS:
如果用非阻塞的方式,那么,执行完READ函数后程序就立即返回,那么我怎么知道什么时间可以读呢?
再谢兄弟的细心解答!
回复 支持 反对

使用道具 举报

发表于 2006-7-24 17:38:51 | 显示全部楼层
是这样的, select 或者 poll 函数可以判断一个文件描述符的状态, 比如待读, 待写等, 而它们在进行这样的判断时, 是可以设置超时的, 因此你在read之前先看看有没有数据需要读, 没有的话就去做别的事情好了.

P.S. 兄弟不必太客气, 论坛本来就是大家互相讨论, 互相帮助的地方
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-7-24 17:57:34 | 显示全部楼层
嗯,您的意思是不是如果检测没有的话,就做别的事时,同时设置一个定时器,指定时间来进行读取操作?因为不管怎么说,我都要读这些数据的,尽管它们有可能从网络上到本机比较慢。
回复 支持 反对

使用道具 举报

发表于 2006-7-24 18:10:18 | 显示全部楼层
对于非读不可的数据, 在不考虑别的因素的情况下, 就让 read 阻塞着等待也未尝不可, 反正不读完也不能进行下一步的处理

但是, 有一些实际情况是需要考虑的, 比如发送方终止或者硬件断开的情况, 这时候不加处理的read操作会导致程序挂住. 因此不妨规定一个超时值, 然后用 select 进行判断, 并把超时后仍然无法读到数据的情况视为错误. 也可以在 read 前用 alarm 设置一个信号来中途打断 read. 总之根据实际的要求来选择程序的结构是有必要的.
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-7-24 18:34:44 | 显示全部楼层
再次谢谢兄弟啦,小弟继续实践去了:)
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表