免费注册 查看新帖 |

Chinaunix

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

[C] socket select [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-11-26 10:01 |只看该作者 |倒序浏览
我在server端socket()了两个,并绑定了两个端口,我把socket的两个描述符加入到读集合,后就用select()来判断。当有连接来的时候,我就fork一个子进程来处理(先accept(),再read(),write()等)。我用两个client端分别连接两个端口,为什么只有1个client端能正常工作(先连接的一个client1能正常工作,而后连接的client2一直再write()处就阻塞了)。在server端也只有两个进程,后连接的client2没有相应的进程,我用gdb调试也是一样,后连接进来的client2再select()那里没有执行,而两个socket都是成功的。但我分别单独执行两个client时都是正常的。我是准备一个端口用来处理一种连接方式(同步短,同步长,异步短,异步长单,异步长双等),我只需要一个server端。请问这是为什么????

再问一下异步短连接的模型是什么样子???
例如同步短连接是
server              client
socket()         socket()   
bind()            connect()
listen()          write()
accept()        read()
read()
write()

同步长连接是:
server                 client
socket()            socket()   
bind()                connect()
listen()              while(1)
while(1)            {
{                         write()
   accept()            read()
   read()            }
   write()
}


/*   server.c  */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <sys/types.h>
static void sig_exit (int signumber)
{
pid_t pid = waitpid(0,NULL,WNOHANG);
/* kill(pid,SIGINT);*/
/*  SIGINT SIGKILL SIGTERM SIGSTOP  */
}
int SocketBuildServerConnect (char *BindIp, unsigned int BindPort,unsigned int MaxListenNum)
{
        int sockfd = socket (AF_INET, SOCK_STREAM, 0);
        if (sockfd < 0)
        {      
                printf ("socket build error\n";
                return -1;
        }      
        struct sockaddr_in my_addr;
        my_addr.sin_family = AF_INET;
        my_addr.sin_port = htons (BindPort);
        if (strcmp (BindIp, "INADDR_ANY" == 0)
                my_addr.sin_addr.s_addr = htonl (INADDR_ANY);
                        
        else   
                my_addr.sin_addr.s_addr = inet_addr (BindIp);
        bzero (&(my_addr.sin_zero), ;
        if ((bind(sockfd, (struct sockaddr *) &my_addr, sizeof (struct sockaddr))) < 0)
        {      
                printf ("socket bind error\n";
                return -2;
        }      
        if ((listen (sockfd, MaxListenNum) < 0))
        {      
                printf ("socket listen error\n";
                return -3;
        }      
        return sockfd;
}
int SocketAccept (int sockfd)
{
        int newsockfd;
        unsigned int socklen = sizeof (struct sockaddr_in);
        struct sockaddr_in their_addr;
        newsockfd = accept (sockfd, (struct sockaddr *) &their_addr, &socklen);
        if (newsockfd < 0)
        {
                printf ("socket accept error\n";
                return -5;
        }
        return newsockfd;
}

int main()
{
int sockfd  = SocketBuildServerConnect("INADDR_ANY",55554,10);
int sockfd2 = SocketBuildServerConnect("INADDR_ANY",55555,10);
if(sockfd<0 || sockfd2<0)
{
   printf("socket error";
   exit(0);
}
struct timeval timeout;
timeout.tv_sec = 60;
timeout.tv_usec = 0;
fd_set readsetfd;
int maxfd = 0;
int ret;
FD_ZERO (&readsetfd);
FD_SET (sockfd, &readsetfd);
FD_SET (sockfd2, &readsetfd);
if(maxfd < sockfd)
  maxfd = sockfd;
if(maxfd < sockfd2)
  maxfd = sockfd2;
pid_t pid;
while(1)
{
  timeout.tv_sec = 30;
  timeout.tv_usec = 0;
  if((ret = select (maxfd + 1, &readsetfd, NULL, NULL, &timeout)) > 0)
  {
   if (FD_ISSET (sockfd, &readsetfd))
   {
    if((pid = fork()) < 0)
    {
     fprintf(stderr,"fork err\n";
     exit(-1);
    }
    else if(pid==0)
    {
     int newsockfd = SocketAccept(sockfd);
     if(newsockfd<0)
     {
      printf("accept error";
      exit(-1);
     }
     close(sockfd);
     close(sockfd2);
     char recvbuf[100],sendbuf[100];
     while(1)
     {
      memset(recvbuf,0,100);
      if((ret=read(newsockfd,recvbuf,100))==-1)exit(-5);
      if(!strncasecmp(recvbuf,"quit",4))
      {
        close(newsockfd);
        exit(0);
      }
      printf("you have message:%s\n",recvbuf);
      memset(sendbuf,0,100);
      sprintf(sendbuf,"Ack -----> %s\n",recvbuf);
      if(send(newsockfd,sendbuf,100,0)==-1)exit(-6);
     }
     exit(0);
    }
    else
    {
     signal (SIGCHLD, sig_exit);
    }
   }
   if (FD_ISSET (sockfd2, &readsetfd))
   {
      if((pid = fork()) < 0)
    {
      fprintf(stderr,"fork err\n";
      exit(-1);
    }
    else if(pid==0)
    {
      int newsockfd = SocketAccept(sockfd2);
      if(newsockfd<0)
      {
        printf("accept error";
        exit(-1);
      }
      close(sockfd2);
      close(sockfd);
      char recvbuf[100],sendbuf[100];
      while(1)
      {
        memset(recvbuf,0,100);
        if((ret=read(newsockfd,recvbuf,100))==-1)exit(-5);
        if(!strncasecmp(recvbuf,"quit",4))
        {
          close(newsockfd);
          exit(0);
        }
        printf("you have message:%s\n",recvbuf);
        memset(sendbuf,0,100);
        sprintf(sendbuf,"Ack -----> %s\n",recvbuf);
        if(send(newsockfd,sendbuf,100,0)==-1)exit(-6);
      }
      exit(0);
    }
    else
    {
      signal (SIGCHLD, sig_exit);
    }
   }
  }
}
return 0;
}


/*  client.c */

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <signal.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <sys/types.h>
#include <netdb.h>
int main()
{
        int sockfd;
        char buffer[100];
         char recvbuf[100];
        struct sockaddr_in their_addr;
        if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
        {
                printf("socket error");
                exit(0);
        }
        their_addr.sin_family=AF_INET;
        their_addr.sin_port=htons(55554);
        their_addr.sin_addr.s_addr=inet_addr("10.0.192.7");
        bzero(&(their_addr.sin_zero),;
        if(connect(sockfd,(struct sockaddr *)&their_addr,sizeof(struct sockaddr))==-1)
        {
                printf("connect error");
                exit(0);
        }
        while(1)
        {
               printf("input send data:");
                if(fgets(buffer,100,stdin)==NULL)
                {
                        exit(0);
                }
                if(!strncasecmp(buffer,"quit",4))
                {
                        send(sockfd,buffer,strlen(buffer),0);
                        printf("quit\n");
                        close(sockfd);
                        exit(0);
                }
                if(send(sockfd,buffer,100,0)==-1)
                {
                        printf("send error");
                        exit(0);
                }
               if(recv(sockfd,recvbuf,100,0) == -1)
              {
                        printf("rec error");
                        exit(-1);
              }
              printf("recv data: %s\n",recvbuf);
        }
        return 0;
}

/* 由于client只是端口不同,故就不重复了,只需该端口就可以了 */

[ 本帖最后由 zhaohonglin 于 2008-11-27 14:28 编辑 ]

cs_socket.rar

2.53 KB, 下载次数: 40

socket

论坛徽章:
0
2 [报告]
发表于 2008-11-26 10:16 |只看该作者
这个太笼统了吧

论坛徽章:
0
3 [报告]
发表于 2008-12-27 20:42 |只看该作者
现在我把源码贴出来了,就是不知道怎么解决,又没有谁遇到过此类问题?
问一下异步短连接的模型是什么样子???
我始终觉得异步端连接不不知是怎么样??
是这样吗?我始终不能确定
server                                client
socket()                            socket()   
bind()                               connect()
listen()                             if (fork() == 0 )
accept()                                  write()
if (fork() == 0 )                if(ffork() > 0)
     read()                                 read()
if(ffork() > 0)
    write()

论坛徽章:
0
4 [报告]
发表于 2008-12-27 21:02 |只看该作者

FD_ZERO (&readsetfd);
FD_SET (sockfd, &readsetfd);
FD_SET (sockfd2, &readsetfd);
写到while循环里面
忘了是select还是FD_ISSET
是会修改readsetfd的

论坛徽章:
1
黑曼巴
日期:2020-02-27 22:54:26
5 [报告]
发表于 2008-12-27 23:33 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP