小试牛刀TCP 网络编程模式,单线程多路复用实例

//server.c




#define USERNAME 0
#define USERPASS 1
#define PORT_SERV 8899
#define LISTENL 12
#define BUFSIZE 1024

typedef struct ClientRequest_t{
	int socet_in;
	int flog;
	int user_id;
}ClientRequest;

struct userinfo{
char username[32];
char userpass[32];
};
typedef struct userinfo userinfo_c;
userinfo_c users[]={{"linux","unix"},{"787","007"},{"gyeve","gaoyi"}};

int send_data(int con,char *buf)
{
	int ret;
	int buf_size = strlen(buf);
	
	while(buf_size >0)
	{
		ret=send(con,buf,buf_size,0);
		if(ret<=0){
		    printf("send is wrong\n");
		return ret;
		}
		buf_size-= ret;
		buf+= ret;
	}
	return ret;
}

int find_name(char *name)
{
    int index=0;
    for(index=0;index<3;index++)
    {
   	 printf("name = %s username = %s\n",name,users[index].username);
        if(strcmp(users[index].username,name)==0)
            return index;
    }
    return -1;
}


int main(int argc,char** argv)
{
	int socket_id,optval,accpt_len;
	struct sockaddr_in server_ad,client_ad;
	int acc_res, ret;
	pid_t pid;
	char buf[BUFSIZE];
	struct timeval tv;
	int i, maxi, maxfd,sockfd; 
	int nready;
	ClientRequest client[FD_SETSIZE]; 

	fd_set readfds, allset;
	int HS_Socket_fd = -1;

	init_Textsignals();
	tv.tv_sec = 60;
	tv.tv_usec = 0;

	socket_id = socket(AF_INET,SOCK_STREAM,0);
	if(socket_id <=0) {
	 perror("socket");
	 exit(1);
	}
	optval=1;
	if(setsockopt(socket_id,SOL_SOCKET,SO_REUSEADDR,&optval,sizeof(int))<0){/*设置窗口重新绑定*/
	perror("setsockopt");
	exit(1);
	}
	memset(&server_ad,0,sizeof(struct sockaddr_in));
	server_ad.sin_family = AF_INET; /*ipv4 of the tcp/ip protocol */
	server_ad.sin_port = htons(PORT_SERV);
	server_ad.sin_addr.s_addr = htonl(INADDR_ANY);/* the localhost ip address */

	if(bind(socket_id,(struct sockaddr *)&server_ad,sizeof(struct sockaddr_in))<0)
	{
	perror("bind");
	exit(3);
	}
	if(listen(socket_id,LISTENL)<0)
	{
	perror("listen");
	exit(4);
	}
	
	accpt_len= sizeof(struct sockaddr_in);

	maxfd = socket_id;                     /* initialize */ 
	maxi = -1;                           /* index into client[] array */ 

	for(i = 0; i < FD_SETSIZE; i++)
	{
		client[i].socet_in = -1; /* -1 indicates available entry */ 
		client[i].user_id = -1;
		client[i].flog = USERNAME;
	}	
		//memset(&client[i],-1,sizeof(ClenitRequset));
		FD_ZERO(&allset); 
		FD_SET(socket_id, &allset); 

	while(1)
	{
		fprintf(stderr,"Waiting....\n");

	 	readfds = allset;  /* structure assignment */ 
              nready = select(maxfd+1, &readfds, NULL, NULL, NULL); 

		 if (nready < 0) 
                       perror("select error"); 

		 if (FD_ISSET(socket_id, &readfds)) { /* new client connection */ 
				acc_res = accept(socket_id,(struct sockaddr *)&client_ad,&accpt_len);
				
				if(acc_res <0)
				{
					if(errno == EINTR)
					{
						continue;
					}
					perror("1accept");
					exit(1);
				}
				fprintf(stderr,"accept a new client ,the ip = %s\n",inet_ntoa(client_ad.sin_addr));
				
				for (i = 0; i < FD_SETSIZE; i++) 
                                    if (client[i].socet_in < 0) { 
                                              client[i].socet_in = acc_res; /* save descriptor */ 
                                              break; 
                                    } 
				 if (i == FD_SETSIZE) { 
				                fprintf(stderr,"too many clients\n"); 
				                exit(1); 
				       } 
			 	 FD_SET(acc_res, &allset);             /* add new descriptor to set */ 
				  if (acc_res > maxfd) 
                                    maxfd = acc_res; /* for select */ 
                          	  if (i > maxi) 
                                    maxi = i;          /* max index in client[] array */ 
				if (--nready == 0) 
                                    continue;          /* no more readable descriptors */ 

		 }
				  

		     for (i = 0; i <= maxi; i++) {          /* check all clients for data*/
				  if ( (sockfd = client[i].socet_in) < 0) 
                                          continue; 
				   if (FD_ISSET(sockfd, &readfds)) { 
						 memset(buf,0,BUFSIZE);
						if((ret=recv(sockfd,buf,BUFSIZE,0))<0){
							perror("recv");
							exit(1);
						}else if(!ret)
						{
							client[i].flog = USERNAME;
							client[i].socet_in= -1; 
							close(sockfd); 
							FD_CLR(sockfd, &allset); 
							fprintf(stderr,"client is die\n");
						break;
						}

						buf[ret]=0;
						fprintf(stderr,"buf = %s\n",buf);
						if(client[i].flog == USERNAME){
							client[i].user_id=find_name(buf);
							switch(client[i].user_id)
							{
							case -1:
								send_data(sockfd,"n\n");
							break;
							default:
								send_data(sockfd,"y\n");
								client[i].flog = USERPASS;
							}
						}
						else if( client[i].flog == USERPASS ){
							if(strcmp(users[client[i].user_id].userpass,buf)==0)
							{
								send_data(sockfd,"y\n");
								send_data(sockfd,"welcome login my cp server\n");
								fprintf(stderr,"%s login\n",users[client[i].user_id].username);
								client[i].flog = USERNAME;
							break;
							}else 
							send_data(sockfd,"n\n");
						}

							if (--nready == 0) 
                          				break;  /* no more readable  descriptors */ 
				   }
		     }
			 	fprintf(stderr,"again.............\n");
		}
}	




//client.c

#include<netinet/in.h>
#include<sys/socket.h>
#include<stdio.h>
#include<strings.h>
#include<arpa/inet.h>


#define LEN 1024
#define VALID 1
#define INVALID 0

int my_recv(int con, char buf[], int len)
{
    int ll;
    ll = recv(con,buf,len,0);
    if(ll<0){
        perror("recv");
        exit(1);
    }
    return ll;
}
void input_mess(int con, const char *string)
{
    char input_buf[32];
    char recv_buf[LEN];
    int flag_userinfo;
    int rev_len;
    do{
        printf("%s:",string);

        gets(input_buf);
        input_buf[strlen(input_buf)]=0;
        printf("%s:",input_buf);
        if(send(con,input_buf,strlen(input_buf),0)<0)
        {
            perror("send");
            exit(1);
        }
        printf("send to server\n");
        if((rev_len = my_recv(con,recv_buf,sizeof(recv_buf)))<0)
        {
            perror("my_recv");
            exit(1);
        }else if(rev_len == 0){
        	printf("server is die\n");
        	exit(1);
        	}
        printf("recv = %s\n",recv_buf);
        if(recv_buf[0]=='y')
            flag_userinfo = VALID;
        else
            flag_userinfo = INVALID;
        memset(recv_buf,0,sizeof(recv_buf));
    }while(flag_userinfo == INVALID);
}
int main(int argc, char *argv[])
{
    int i,ret;
    int conn_fd,socketd;
    char recvbuf[LEN]={0};
    struct sockaddr_in serv_addr;

    if(argc!=5)
    {
        printf("the argc is not equals 5\n");
        return -1;
    }
    memset(recvbuf,0,LEN);
    memset(&serv_addr,0,sizeof(struct sockaddr_in));
    serv_addr.sin_family=AF_INET;
    for(i=0;i<argc;i++)
    {
        if(strcmp(argv[i],"-a")==0)
        {
            i++;
            if(inet_aton(argv[i],&serv_addr.sin_addr)==0){
                printf("invaild server ip address \n");
                exit(1);
            }/*如果该for中两个条件的判定是通过两个if链接的,那么要使用continue*/
        }
        else if(strcmp(argv[i],"-p")==0)
        {
            i++;
            int port = atoi(argv[i]);
            if(port<0||port>=65536) {
                printf("the port is overwiding\n");
                break;
            }else{
            serv_addr.sin_port = htons(port);
            }
        }
    }
    if(serv_addr.sin_addr.s_addr == 0||serv_addr.sin_port == 0)
    {
        printf("usage [-a] [address] [-p] [port]\n");
        exit(1);
    }
    socketd = socket(AF_INET,SOCK_STREAM,0);
    conn_fd = connect(socketd,(struct sockaddr*)&serv_addr,sizeof(struct sockaddr));
    if(conn_fd<0)
    {
        perror("connect");
        exit(1);
    }
    input_mess(socketd,"username");
    input_mess(socketd,"userpass");
    if((ret=my_recv(socketd,recvbuf,LEN))<0)
    {
        printf("data is too long");
        exit(1);
    }
    recvbuf[ret]=0;
    printf("%s\n",recvbuf);
    

    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值