正在加载……
专注、离线、切勿分心
如何实现多个客户端连接,服务器有相应。

服务器是只有一个线程,主线程

1、能够监听客户端的连接请求;
2、能够接收已经连接的客户端发送来的数据。
3、已经连接的客户端发送某个数据,回复相同数据给它。

sfd
new_fd1,...
select
fd_set tmpset

客户端不断开,不停的输入话语,发送给服务器端

1、服务器端和客户端进行即时聊天,一个服务器端,一个客户端。

tcp_server_s.c tcp_client_s.c
#include"func.h"
#define NUM 10
int main(int argc,char** argv)
{
        if(argc!=3)
        {
                printf("error args\n");
                return -1;
        }
        int sfd=socket(AF_INET,SOCK_STREAM,0);
        if(-1==sfd)
        {
                perror("socket");
                return -1;
        }
        struct sockaddr_in ser;
        memset(&ser,0,sizeof(ser));
        ser.sin_family=AF_INET;
        ser.sin_port=htons(atoi(argv[2]));
        ser.sin_addr.s_addr=inet_addr(argv[1]);
        int ret;
        ret=bind(sfd,(struct sockaddr*)&ser,sizeof(struct sockaddr));
        if(-1==ret)
        {
                perror("bind");
                return -1;
        }
        ret=listen(sfd,NUM);
        if(-1==ret)
        {
                perror("listen");
                return -1;
        }
        printf("listen success\n");
        struct sockaddr_in client;
        memset(&client,0,sizeof(client));
        int addrlen=sizeof(struct sockaddr);
        fd_set rdset;
        int new_fd[NUM]={0};
        int i=0;
        int j;
        fd_set tmpset;
        FD_ZERO(&tmpset);
        FD_SET(sfd,&tmpset);
        char buf[128]={0};
        while(1)
        {
                FD_ZERO(&rdset);
                memcpy(&rdset,&tmpset,sizeof(rdset));
                ret=select(NUM+4,&rdset,NULL,NULL,NULL);
                if(ret>0)
                {
                        if(FD_ISSET(sfd,&rdset))
                        {
                                new_fd[i]=accept(sfd,(struct sockaddr*)&client,&addrlen);
                                if(-1==new_fd[i])
                                {
                                        perror("accept");
                                        return -1;
                                }
                                printf("client ip = %s port = %d\n",inet_ntoa(client.sin_addr),nto    hs(client.sin_port));
                                FD_SET(new_fd[i],&tmpset);
                                i++;
                        }
                        j=0;
                        while(new_fd[j]!=0)
                        {
                                if(FD_ISSET(new_fd[j],&rdset))
                                {
                                        memset(buf,0,sizeof(buf));
                                        ret=recv(new_fd[j],buf,sizeof(buf),0);
                                        if(ret>0)
                                        {
                                                printf("newfd %d recv buf =%s\n",newfd[j],buf);
                                                ret=send(new_fd[j],buf,strlen(buf),0);
                                                if(ret==-1)
                                                {
                                                        perror("send");
                                                        return -1;
                                                }
                                                else if(ret==0)   //客户端断开和管道一样,读到0,服务器这边会一直显示打印0,所以要关闭;
                                                {
                                                        printf("close client ip = %s port = %d\n",inet_ntoa(client    .sin_addr),ntohs(client.sin_port));
                                                        close(new_fd[j]);
                                                        FD_CLR(new_fd[j],&tmpset);
                                                }
                                        }
                                }
                                j++;
                        }
                }
        }
        return 0;
}
#include"func.h"

int main(int argc,char** argv)
{
        if(argc!=3)
        {
                printf("error args\n");
                return -1;
        }
        int sfd=socket(AF_INET,SOCK_STREAM,0);
        if(-1==sfd)
        {
                perror("socket");
                return -1;
        }
        struct sockaddr_in ser;
        memset(&ser,0,sizeof(ser));
        ser.sin_family=AF_INET;
        ser.sin_port=htons(atoi(argv[2]));
        ser.sin_addr.s_addr=inet_addr(argv[1]);
        int ret;
        ret=connect(sfd,(struct sockaddr*)&ser,sizeof(struct sockaddr));
        if(-1==ret)
        {
                perror("connect");
                return -1;
        }
        char buf[128]={0};
        while(1)
        {
                memset(buf,0,sizeof(buf));
                ret=read(0,buf,sizeof(buf));
                if(ret<=0)
                {
                        break;
                }
                ret=send(sfd,buf,strlen(buf)-1,0);
                if(-1==ret)
                {
                        perror("send");
                        return -1;
                }
                memset(buf,0,sizeof(buf));
                ret=recv(sfd,buf,sizeof(buf),0);
                if(-1==ret)
                {
                        perror("recv");
                        return -1;
                }
                printf("recv from server:%s\n",buf);
        }
        return 0;
}

func.h Makefile
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/select.h>
tcp_server_s:tcp_server_s.c tcp_client_s.c
                    gcc tcp_server_s.c -o tcp_server_s
                    gcc tcp_client_s.c -o tcp_client_s
.PHONY:clean
clean:
                    rm tcp_server_s tcp_client_s

  

  




  






posted on 2018-03-14 08:35  正在加载……  阅读(235)  评论(0编辑  收藏  举报