免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1803 | 回复: 8
打印 上一主题 下一主题

高手帮帮忙,socket的问题。 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-10-15 16:50 |只看该作者 |倒序浏览
本来打算是初始化一个队列,然后开两个进程,一个接收请求并把接收结果入队列,另外一个是出队列的,但是不知道为什么总出队列进程一直打印队列是空的。队列的程序没有错的,我测试过了很多遍了。请各位帮帮忙吧。

  1. #include <pthread.h>
  2. #include <sys/types.h>
  3. #include <sys/socket.h>
  4. #include <unistd.h>
  5. #include <netinet/in.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include "queue.h"

  10. #define BACKLOG 1024

  11. static queue *global_queue = NULL;//队列全局变量

  12. void server(int argc, char **argv);
  13. void working();

  14. void destroy(void *arg) {
  15.         free(arg);
  16. }

  17. /* recv: "id:domain" */
  18. void *proccess(void *arg) {
  19.         int fd = *(int *)arg;
  20.         char buffer[1024];
  21.         ssize_t readsize;
  22.         char *entry;
  23.        
  24.         readsize = recv(fd, buffer, 1024, MSG_DONTWAIT);
  25.        
  26.         queue_entry(global_queue, strdup(buffer)); //入队列

  27.         send(fd, "OK", strlen("OK"), MSG_DONTWAIT);
  28.         close(fd);
  29.        
  30.         pthread_exit(NULL);
  31. }

  32. int main(int argc, char **argv) {
  33.         global_queue = queue_init();//初始化队列
  34.         pid_t pid;
  35.        
  36.         pid = fork();
  37.         if (pid == 0) {
  38.                 server(argc, argv);
  39.         } else if (pid > 0) {
  40.                 working();
  41.         } else {
  42.                 printf("Can not fork.\n");
  43.         }
  44.        
  45.         return 0;
  46. }

  47. void server(int argc, char **argv) {
  48.         int serverfd, clientfd;
  49.         struct sockaddr_in server_addr;
  50.         struct sockaddr_in client_addr;
  51.         int err;
  52.         pthread_t pid;
  53.         int port;
  54.        
  55.         if (argc != 3) {
  56.                 fprintf(stderr, "Error: server <ip> <port>.\n");
  57.                 return;
  58.         }
  59.        
  60.         port = atoi(argv[2]);
  61.        
  62.         if (global_queue == NULL) {
  63.                 fprintf(stderr, "Can not create queue.\n");
  64.                 return;
  65.         }
  66.        
  67.         serverfd = socket(AF_INET, SOCK_STREAM, 0);
  68.         if (serverfd < 0) {
  69.                 fprintf(stderr, "Can not open socket.\n");
  70.                 return;
  71.         }
  72.        
  73.         bzero(&server_addr, sizeof(server_addr));
  74.         server_addr.sin_family = AF_INET;
  75.         server_addr.sin_addr.s_addr = inet_addr(argv[1]);
  76.         server_addr.sin_port = htons(port);
  77.        
  78.         err = bind(serverfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
  79.         if (err < 0) {
  80.                 fprintf(stderr, "Can not bind socket.\n");
  81.                 return;
  82.         }
  83.        
  84.         err = listen(serverfd, BACKLOG);
  85.         if (err < 0) {
  86.                 fprintf(stderr, "Can not listen socket.\n");
  87.                 return;
  88.         }
  89.        
  90.         for (;;) {
  91.                 int addrlen = sizeof(struct sockaddr);
  92.                
  93.                 clientfd = accept(serverfd, (struct sockaddr *)&client_addr, &addrlen);
  94.                 if (clientfd < 0) {
  95.                         printf("Can not accept socket.\n");
  96.                         continue;
  97.                 }
  98.                
  99.                 err = pthread_create(&pid, NULL, proccess, &clientfd);
  100.                 if (err < 0) {
  101.                         printf("Can not create pthread.\n");
  102.                         close(clientfd);
  103.                 }
  104.         }
  105.        
  106.         queue_destroy(global_queue, destroy);
  107. }

  108. void working() {
  109.         char *entry;
  110.         for (;;) {
  111.                 if (!queue_empty(global_queue)) {//如果队列不为空
  112.                         entry = (char *)queue_front(global_queue);//出队列
  113.                        
  114.                         printf("%s\n", entry);
  115.                 }
  116.                 sleep(2);
  117.         }
  118.        
  119.         return;
  120. }
复制代码

论坛徽章:
0
2 [报告]
发表于 2010-10-15 16:55 |只看该作者
请解谢谢!!

论坛徽章:
1
申猴
日期:2014-02-11 14:50:31
3 [报告]
发表于 2010-10-15 17:19 |只看该作者
为什么每个客户有一个线程了,还要用到:MSG_DONTWAIT标记 ?
如果网络慢,而此时线程运行到recv(),由于recv()有MSG_DONTWAIT,它不等数据的到达就返回了,不是就接收不到数据了。

另外:
pthread_create(&pid, NULL, proccess, &clientfd);

这个有隐患

论坛徽章:
0
4 [报告]
发表于 2010-10-15 17:22 |只看该作者
为什么每个客户有一个线程了,还要用到:MSG_DONTWAIT标记 ?
如果网络慢,而此时线程运行到recv(),由于r ...
chenzhanyiczy 发表于 2010-10-15 17:19



    请问怎么设计呢?我第一次写服务端程序的!

论坛徽章:
1
申猴
日期:2014-02-11 14:50:31
5 [报告]
发表于 2010-10-15 17:33 |只看该作者
最简单的:
while()
{
  recv();   不要加MSG_DONTWAIT,MSG_DONTWAIT是非阻塞的
  send();
}

另外,队列有锁吗?

论坛徽章:
0
6 [报告]
发表于 2010-10-15 17:41 |只看该作者
楼主解决没?

论坛徽章:
0
7 [报告]
发表于 2010-10-16 11:25 |只看该作者
应该是MSG_WAITALL 吧? recv那里

论坛徽章:
0
8 [报告]
发表于 2010-10-16 11:51 |只看该作者
我觉得是申请了两个进程的问题。

论坛徽章:
0
9 [报告]
发表于 2010-10-16 18:32 |只看该作者
你这个queue是怎么实现的,进程之间是不共享全局变量的。如果你是自己搞的链表之类的做的,就算新数据放入了队列,另外一个进程也是收不到的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP