- 论坛徽章:
- 0
|
我在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 编辑 ] |
|