精华内容
下载资源
问答
  •  } 客户端代码: #include #include #include #include #include #include #include char dict(char temp) { if(temp == 'Z') { return 'A'; } return temp+1; } int main() { int ...

    声明:这部分代码是摘抄别人的

    有时候需要写代码手里也没有现成的代码,挺麻烦的所有放在这里提高效率。

    server端的代码:

    1. #include <sys/types.h>  
    2. #include <sys/socket.h>  
    3. #include <stdio.h>  
    4. #include <netinet/in.h>  
    5. #include <arpa/inet.h>  
    6. #include <unistd.h>  
    7. #include <stdlib.h>  
    8. int main()  
    9. {  
    10.     int sockfd;  
    11.     int len;  
    12.     struct sockaddr_in address;  
    13.     int result;  
    14.     int i,byte;  
    15.     char char_recv,char_send;  
    16.     if((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1)  
    17.     {  
    18.         perror("socket");  
    19.         exit(EXIT_FAILURE);  
    20.     }  
    21.     address.sin_family = AF_INET;  
    22.     address.sin_addr.s_addr = inet_addr("127.0.0.1");  
    23.     address.sin_port = 8080;  
    24.     len = sizeof(address);  
    25.     if((result = connect(sockfd,(struct sockaddr *)&address,len)) == -1)  
    26.     {  
    27.         perror("connect");  
    28.         exit(EXIT_FAILURE);  
    29.     }  
    30.   
    31.     printf("please enter the context you want to send to server :");  
    32.     scanf("%c",&char_send);  
    33.   
    34.     if(byte = send(sockfd,&char_send,1,0) == -1)  
    35.     {  
    36.         perror("send");  
    37.         exit(EXIT_FAILURE);  
    38.     }  
    39.     if(byte = recv(sockfd,&char_recv,1,0) == -1)  
    40.     {  
    41.         perror("recv");  
    42.         exit(EXIT_FAILURE);  
    43.     }  
    44.     printf("receive from server %c\n",char_recv);  
    45.       
    46.     close(sockfd);  
    47.     exit(0);  
    48. }  

    客户端代码:

    1. #include <sys/types.h>  
    2. #include <sys/socket.h>  
    3. #include <stdio.h>  
    4. #include <netinet/in.h>  
    5. #include <arpa/inet.h>  
    6. #include <unistd.h>  
    7. #include <stdlib.h>  
    8. char dict(char temp)  
    9. {  
    10.     if(temp == 'Z')  
    11.     {  
    12.         return 'A';  
    13.     }  
    14.     return temp+1;  
    15. }  
    16. int main()  
    17. {  
    18.     int server_sockfd,client_sockfd;  
    19.     int server_len,client_len;  
    20.     struct sockaddr_in server_address;  
    21.     struct sockaddr_in client_address;  
    22.     int i,btye;  
    23.     char char_recv,char_send;  
    24.       
    25.     server_address.sin_family = AF_INET;  
    26.     server_address.sin_addr.s_addr = inet_addr("127.0.0.1");  
    27.     server_address.sin_port = 8080;  
    28.     server_len = sizeof(server_address);  
    29.       
    30.     server_sockfd = socket(AF_INET,SOCK_STREAM,0);  
    31.       
    32.     bind(server_sockfd,(struct sockaddr *)&server_address,server_len);  
    33.       
    34.     listen(server_sockfd,5);  
    35.     printf("server waiting for connect\n");  
    36.       
    37.     client_len = sizeof(client_address);  
    38.     client_sockfd = accept(server_sockfd,(struct sockaddr *)&client_address,(socklen_t *)&client_len);  
    39.       
    40.     if(btye = recv(client_sockfd,&char_recv,1,0) == -1)  
    41.     {  
    42.         perror("recv");  
    43.         exit(EXIT_FAILURE);  
    44.     }  
    45.     printf("receive from client is %c\n",char_recv);  
    46.     char_send = dict(char_recv);  
    47.     if(btye = send(client_sockfd,&char_send,1,0) == -1)  
    48.     {  
    49.         perror("send");  
    50.         exit(EXIT_FAILURE);  
    51.     }  
    52.   
    53.     shutdown(client_sockfd,2);  
    54.     shutdown(server_sockfd,2);   
    55.     return 0;  

     

    展开全文
  • my_socket.c: #include "my_socket.h" int create_tcp_client(const int server_port, const char* server_ip) { int sock_fd = -1; int ret; struct sockaddr_in sad...

    my_socket.c:

    #include "my_socket.h"
    
    int createTcpClient(const int serPort, const char* serIp)
    {
        int                serFd = -1;
        int                ret;
        struct sockaddr_in saddr;
    
        serFd = socket(PF_INET, SOCK_STREAM, 0);
        if (serFd < 0)
        {
            perror("socket");
            return -1;
        }
    
        saddr.sin_family = AF_INET;
        saddr.sin_port = htons(serPort);
        inet_pton(AF_INET, serIp, &saddr.sin_addr.s_addr);
    
        ret = connect(serFd, (struct sockaddr*)&saddr, sizeof(saddr));
        if (ret < 0)
        {
            perror("connect");
            if (serFd > 0)
            {
                close(serFd);
            }
            return -1;
        }
        return serFd;
    }
    
    int createTcpServer(const int serPort)
    {
        int                serFd;
        struct sockaddr_in serAddr;
        struct sockaddr_in cliAddr;
        int                addrLen = sizeof(cliAddr);
        int                cliFd = -1;
        char               buffer[4096];
        int                iDataNum;
        int                ret = -1;
        if ((serFd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
        {
            perror("socket");
            return 1;
        }
    
        bzero(&serAddr, sizeof(serAddr));
        //初始化服务器端的套接字,并用htons和htonl将端口和地址转成网络字节序
        serAddr.sin_family = AF_INET;
        serAddr.sin_port = htons(serPort);
        // ip可是是本服务器的ip,也可以用宏INADDR_ANY代替,代表0.0.0.0,表明所有地址
        serAddr.sin_addr.s_addr = htonl(INADDR_ANY);
        //对于bind,accept之类的函数,里面套接字参数都是需要强制转换成(struct sockaddr
        //*) bind三个参数:服务器端的套接字的文件描述符,
        int opt = 1;
        setsockopt(serFd, SOL_SOCKET, SO_REUSEADDR, (const void*)&opt, sizeof(opt));
        if (bind(serFd, (struct sockaddr*)&serAddr, sizeof(serAddr)) < 0)
        {
            perror("connect");
            return 1;
        }
        //设置服务器上的socket为监听状态
        if (listen(serFd, 5) < 0)
        {
            perror("listen");
            return 1;
        }
    
        printf("Listening on port: %d\n", serPort);
    
        fd_set serSet, rserSet;
        FD_ZERO(&serSet);
        FD_SET(serFd, &serSet);
    
        int            maxfd = serFd;
        struct timeval tv0;
        while (1)
        {
            rserSet = serSet;
            printf("wait select ....\n");
            tv0.tv_sec = 5;
            tv0.tv_usec = 0;
            ret = select(maxfd + 1, &rserSet, NULL, NULL,&tv0);  //对读进行操作等待(NULL时无限等待)
    
            if (ret == 0)
            {
                printf("select ret == 0 ....\n");
                continue;
            }
            if (ret < 0)
            {
                perror("select");
                sleep(1);
                continue;
            }
            if (FD_ISSET(serFd, &rserSet))
            {
                if (cliFd > 0)
                {
                    printf("client(IP:%s port:%d) is broken ...\n",inet_ntoa(cliAddr.sin_addr),htons(cliAddr.sin_port));
                    close(cliFd);
                    cliFd = -1;
                }
                cliFd = accept(serFd, (struct sockaddr*)&cliAddr, (socklen_t*)&addrLen);
                if (cliFd < 0)
                {
                    perror("accept");
                    continue;
                }
                printf("\nrecv cliFd data...\n");
                // inet_ntoa   ip地址转换函数,将网络字节序IP转换为点分十进制IP
                //表达式:char *inet_ntoa (struct in_addr);
                printf("client(IP:%s port:%d) connect ...\n",inet_ntoa(cliAddr.sin_addr),htons(cliAddr.sin_port));
                if (cliFd > maxfd)
                {
                    maxfd = cliFd;
                }
                FD_SET(cliFd, &serSet);
            }
            else
            {
                if (cliFd < 0)
                {
                    continue;
                }
                memset(buffer, 0, 4096);
                iDataNum = recv(cliFd, buffer, 4096, MSG_DONTWAIT);
                if (iDataNum <= 0)
                {
                    FD_CLR(cliFd, &serSet);
    
                    if (iDataNum < 0)
                    {
                        perror("recv");
                    }
                    else
                    {
                        if (cliFd > 0)
                        {
                            printf("client(IP:%s port:%d) disconnect ...\n",inet_ntoa(cliAddr.sin_addr),htons(cliAddr.sin_port));
                            close(cliFd);
                        }
                        cliFd = -1;
                    }
                    continue;
                }
                else
                {
                    printf("buffer form cli: %s\n", buffer);
                }
            }
        }
        if(serFd > 0)close(serFd);
        if(cliFd > 0)close(cliFd);
        return 0;
    }

    ser.c:

    #include "my_socket.h"
    
    int main()
    {
        createTcpServer(8888);
    }

     

    cli.c:

    #include "my_socket.h"
    
    int main()
    {
        int  serFd = createTcpClient(8888, "127.0.0.1");
        char buf[] = "abcdefg";
        int  ret = -1;
        while (1)
        {
            ret = send(serFd, buf, sizeof(buf), 0);
            if (ret < 0)
            {
                perror("send");
                break;
            }
            sleep(1);
        }
        if(serFd > 0)close(serFd);
    }

     

    展开全文
  • 只能接收一个连接请求的TCP服务器。 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <ctype.h> #include <sys/types.h> #...

    只能接收一个连接请求的TCP服务器 。

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    #include <ctype.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <arpa/inet.h>
    
    void sys_err(char *error)
    {
        perror(error);
        exit(1);
    }
    
    int main(int argc, char **argv)
    {
        int lfd;
        int ret;
        struct sockaddr_in serv_addr;
        //创建socket,指定IPv4协议族 TCP协议
        lfd = socket(AF_INET, SOCK_STREAM, 0);
        if (lfd == -1)
        {
    	    sys_err("socket error");
        }
        //初始化一个地址结构 man 7 ip 查看对应信息
        serv_addr.sin_family = AF_INET;                    //选择协议族为IPv4
        serv_addr.sin_port = htons(6666);                  //绑定端口号 
        serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);     //监听本地所有IP地址
        //绑定服务器地址结构
        ret = bind(lfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
        if (ret == -1)
        {
    	    sys_err("bind error");
        }
    
        //设置监听上限,设定链接上限,注意此处不阻塞,同一时刻允许向服务器发起链接请求的数量
        ret = listen(lfd, 128);
        if (ret == -1)
        {
    	    sys_err("listen error");
        }
    
        //等待并接收连接请求
        struct sockaddr_in client_addr;
        socklen_t len = sizeof(client_addr);
        //监听客户端链接, 会阻塞
        int cfd = accept(lfd, (struct sockaddr *)&client_addr, &len);
        if (cfd == -1)
        {
    	    sys_err("accept error");
        }
    
        printf("accept successful\n");
        char ipbuf[64] = { 0 };
        printf("client ip:%s, port:%d\n", 
            inet_ntop(AF_INET, &client_addr.sin_addr.s_addr, ipbuf, sizeof(ipbuf)), 
            ntohs(client_addr.sin_port));
    
        while (1)
        {
    	    char buf[1024] = { 0 };
    	    int len = read(cfd, buf, sizeof(buf));
    	    if (len == -1)
    	    {
    	        sys_err("read error");
    	    }
    	    else if (len == 0)
    	    {
    	        printf("客户端断开连接\n");
    	        close(cfd);
    	        break;
    	    }
    	    else
    	    {
    	        printf("recv buf:%s\n",buf);
    
    	        for(int i=0; i<len; i++)
    	        {
    		        buf[i] = toupper(buf[i]);
    	        }
    	        printf("send buf: %s", buf);
    	        write(cfd, buf, len);
    	    }
        }
    
        close(lfd);
        return 0;
    }
    

     

     简单的客户端实现

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <arpa/inet.h>
    #include <fcntl.h>
    
    void sys_err(char *error)
    {
        perror(error);
        exit(1);
    }
    
    int main(int argc, char **argv)
    {
        int fd = socket(AF_INET, SOCK_STREAM, 0);
        if (fd == -1)
        {
    	sys_err("socket error");
        }
        struct sockaddr_in server_addr;
        server_addr.sin_family = AF_INET;
        server_addr.sin_port = htons(6666);
        inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr.s_addr);
    
        //与服务器建立连接
        int ret = connect(fd, (struct sockaddr *)&server_addr, sizeof(server_addr));
        if (ret == -1)
        {
    	sys_err("connect error");
        }
    
        while (1)
        {
    	char buf[512];
    	fgets(buf, sizeof(buf), stdin);
    	//将输入的数据发给服务器
    	write(fd, buf, strlen(buf));
    
    	//接收服务器发过来的数据
    	int len = read(fd, buf, sizeof(buf));
    	if (len == 0)
    	{
    	    sys_err("read error");
    	}
    	else if (len == 0)
    	{
    	    printf("服务器端关闭了连接\n");
    	    break;
    	}
    	else
    	{
    	    printf("recv buf: %s\n", buf);
    	}
        }
        
        close(fd);
        return 0;
    }
    

    多进程服务器实现多个客户端连接

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <arpa/inet.h>
    #include <sys/wait.h>
    #include <signal.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <errno.h>
    #include <ctype.h>
    
    void sys_err(const char *str)
    {
        perror(str);
        exit(-1);
    }
    
    //子进程回收
    void recycle(int num)
    {
        int ret;
        while ((ret = waitpid(-1, NULL, WNOHANG)) > 0)
        {
            printf("recycle pid %d\n", ret);
        }
    }
    
    int main(int argc, char **argv)
    {
        pid_t pid;
        int lfd, cfd;
        int ret;
        struct sockaddr_in server;
        struct sockaddr_in client;
        socklen_t client_len;
        lfd = socket(AF_INET, SOCK_STREAM, 0);
        if (lfd == -1)
        {
            sys_err("socket error");
        }
        //绑定服务器地址信息
        server.sin_family = AF_INET;
        server.sin_port   = htons(6666);
        server.sin_addr.s_addr = htonl(INADDR_ANY);
        ret = bind(lfd, (struct sockaddr *)&server, sizeof(server));
        if (ret == -1)
        {
            sys_err("bind error");
        }
        ret = listen(lfd, 128);
        if (ret == -1)
        {
            sys_err("listen error");
        }
        //注册子进程回收处理
        struct sigaction act;
        act.sa_flags = 0;
        act.sa_handler = recycle;
        sigemptyset(&act.sa_mask);
        sigaction(SIGCHLD, &act, NULL);
        //开始循环接收客户端的连接请求
        while (1)
        {
            int readlen;
            char bufip[64] = { 0 };
            char buf[1024] = { 0 };
            client_len = sizeof(client);
            // 父进程接收连接请求
            // accept阻塞的时候被信号中断, 处理信号对应的操作之后
            // 回来之后不阻塞了, 直接返回-1, 这时候 errno==EINTR
            cfd = accept(lfd, (struct sockaddr *)&client, &client_len);
            while ( cfd == -1 && errno == EINTR)
            {
                cfd = accept(lfd, (struct sockaddr *)&client, &client_len);
            }
            printf("connect sucessful\n");
            pid = fork();
            if (pid < 0)
            {
                sys_err("fork error");
            }
            else if (pid == 0)
            {
                //关闭用于监听的fd
                close(lfd);
                //子进程
                printf("client ip:%s, port %d\n",
                        inet_ntop(AF_INET, &client.sin_addr.s_addr, bufip, sizeof(bufip)),
                        ntohs(client.sin_port));
    
                while (1)
                {
                    readlen = read(cfd, buf, sizeof(buf));
                    if (readlen == -1)
                    {
                        sys_err("read error");
                    }
                    else if (readlen == 0)
                    {
                        printf("客户端断开连接\n");
                        close(cfd);
                        break;
                    }
                    else
                    {
                        //正常读取
                        printf("recv from %s, buf: %s\b", bufip, buf);
                        write(cfd, buf, readlen);
                    }
                }
                return 1;
            }
            else
            {
                //父进程
                //关闭用于通信的fd
                close(cfd);
            }
        }
        close(lfd);
        return 0;
    }
    

     

     多线程服务器实现多个客户端连接

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include <pthread.h>
    #include <errno.h>
    
    extern errno;
    
    typedef struct sockinfo
    {
        int fd;
        pthread_t tid;
        struct sockaddr_in addr;
    } sockinfo;
    
    void sys_err(const char *str)
    {
        perror(str);
        exit(1);
    }
    
    void *worker(void *arg)
    {
        char bufip[64];
        char buf[1024];
        sockinfo *sock = (sockinfo *)arg;
        printf("pthread id %lu, client ip: %s, port: %d\n",
                sock->tid,
                inet_ntop(AF_INET, &sock->addr.sin_addr.s_addr, bufip, sizeof(bufip)),
                ntohs(sock->addr.sin_port));
    
        while (1)
        {
            int len = read(sock->fd, buf, sizeof(buf));
            if (len == -1)
            {
                printf("read error %s\n", strerror(errno));
                pthread_exit(NULL);
            }
            else if (len == 0)
            {
                printf("有客户端断开连接了\n");
                close(sock->fd);
                break;
            }
            else
            {
                printf("recv from ip %s, buf %s\n", bufip, buf);
                write(sock->fd, buf, len);
            }
        }
        return NULL;
    }
    
    int main(int argc, char **argv)
    {
        int lfd;
        int ret;
        sockinfo sock[256];
        int index = 0;
        socklen_t client_len;
    
        lfd = socket(AF_INET, SOCK_STREAM, 0);
        if (lfd == -1)
        {
            sys_err("socket error");
        }
        struct sockaddr_in server;
        server.sin_family = AF_INET;
        server.sin_port   = htons(6666);
        server.sin_addr.s_addr = htonl(INADDR_ANY);
        ret = bind(lfd, (struct sockaddr *)&server, sizeof(server));
        if (ret == -1)
        {
            sys_err("bind error");
        }
        ret = listen(lfd, 128);
        if (ret == -1)
        {
            sys_err("listen error");
        }
    
        // cfd = -1
        for (index=0; index < sizeof(sock)/sizeof(sock[0]); index++)
        {
            sock[index].fd = -1;
        }
        //等待接收连接请求
        while (1)
        {
            for (index=0; index < sizeof(sock)/sizeof(sock[0]); index++)
            {
                if (sock[index].fd == -1 )
                {
                    break;
                }
            }
    
            if (index == 256)
            {
                break;
            }
            client_len = sizeof(struct sockaddr_in);
            sock[index].fd = accept(lfd, (struct sockaddr *)&sock[index].addr, &client_len);
            if (sock[index].fd == -1)
            {
                sys_err("accept error");
            }
            ret = pthread_create(&sock[index].tid, NULL, worker, &sock[index]);
            if (ret != 0)
            {
                sys_err("pthread create error");
            }
            pthread_detach(sock[index].tid);
        }
        close(lfd);
        pthread_exit(NULL);
    }
    

     

    使用select

    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    
    void sys_err(const char *str)
    {
        perror(str);
        exit(1);
    }
    
    int main(int argc, char **argv)
    {
        struct sockaddr_in server;
        int lfd;
        int ret;
    
        //创建socket
        lfd = socket(AF_INET, SOCK_STREAM, 0);
        if (lfd == -1)
        {
            sys_err("socket error");
        }
        //bind
        server.sin_family = AF_INET;
        server.sin_port   = htons(6666);
        server.sin_addr.s_addr = htonl(INADDR_ANY);
        ret = bind(lfd, (struct sockaddr *)&server, sizeof(server));
        if (ret == -1)
        {
            sys_err("bind error");
        }
        //设置监听上限
        ret = listen(lfd, 128);
        if (ret == -1)
        {
            sys_err("listen error");
        }
    
        //等待接收连接请求
        struct sockaddr_in client;
        socklen_t client_len = sizeof(client);
    
        int maxfd = lfd;
        fd_set reads, temp;
        //初始化fd集
        FD_ZERO(&reads);
        FD_SET(lfd, &reads);
    
        while (1)
        {
            temp = reads;
            ret = select(maxfd+1, &temp, NULL, NULL, NULL);
            if (ret == -1)
            {
                sys_err("select error");
            }
            if (FD_ISSET(lfd, &temp))
            {
                //接受连接请求,不阻塞
                int cfd = accept(lfd, (struct sockaddr *)&client, &client_len);
                if (cfd == -1)
                {
                    sys_err("accept error");
                }
                char ip[64];
                printf("new client IP:%s, port:%d\n",
                       inet_ntop(AF_INET, &client.sin_addr.s_addr, ip, sizeof(ip)),
                       ntohs(client.sin_port));
                //将新的fd添加到集合中
                FD_SET(cfd, &reads);
                //更新最大fd
                maxfd = maxfd < cfd ? cfd : maxfd;
            }
            //数据读写
            for (int i=lfd+1; i<=maxfd; i++)
            {
                if (FD_ISSET(i, &temp))
                {
                    char buf[1024] = { 0 };
                    int len = recv(i, buf, sizeof(buf), 0);
                    if (len == -1)
                    {
                        perror("recv error");
                    }
                    else if (len == 0)
                    {
                        printf("client 断开连接\n");
                        close(i);
                        //从集合中删除i
                        FD_CLR(i, &reads);
                    }
                    else
                    {
                        printf("recv buf: %s\n", buf);
                        send(i, buf, strlen(buf)+1, 0);
                    }
                }
            }
        }
        close(lfd);
        return 0;
    }
    

     

    使用poll

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <ctype.h>
    #include <poll.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    
    int main(int argc, char **argv)
    {
        int lfd;
        struct sockaddr_in server, client;
        socklen_t client_len;
        int ret;
    
        lfd = socket(AF_INET, SOCK_STREAM, 0);
        if (lfd == -1)
        {
            perror("socket error");
            exit(1);
        }
        server.sin_family = AF_INET;
        server.sin_port   = htons(6666);
        server.sin_addr.s_addr = htonl(INADDR_ANY);
        ret = bind(lfd, (struct sockaddr *)&server, sizeof(server));
        if (ret == -1)
        {
            perror("bind error");
            exit(1);
        }
        ret = listen(lfd, 128);
        if (ret == -1)
        {
            perror("listen error");
            exit(1);
        }
        //poll结构体
        struct pollfd allfd[1024];
        int max_index = 0;
        for (int i=0; i<1024; i++)
        {
            allfd[i].fd = -1;
            allfd[i].events = POLLIN;
        }
        allfd[0].fd = lfd;
        allfd[0].events = POLLIN;
    
        while (1)
        {
            int i=0;
            ret = poll(allfd, max_index+1, -1);
            if (ret == -1)
            {
                perror("poll error");
                exit(1);
            }
            if (allfd[0].revents & POLLIN)
            {
                char ip[64];
                client_len = sizeof(client);
                int cfd = accept(lfd, (struct sockaddr*)&client, &client_len);
                if (cfd == -1)
                {
                    perror("accept error");
                    exit(1);
                }
                printf("client ip:%s, port:%d\n",
                        inet_ntop(AF_INET, &client.sin_addr.s_addr, ip, sizeof(ip)),
                        ntohs(client.sin_port));
                for (i=0; i<1024; i++)
                {
                    if (allfd[i].fd == -1)
                    {
                        allfd[i].fd = cfd;
                        break;
                    }
                }
                //last
                max_index = max_index < i? i: max_index;
            }
            //foreach
            for (i=1; i<=max_index; i++)
            {
                int fd = allfd[i].fd;
                if (fd == -1)
                {
                    continue;
                }
                if (allfd[i].revents & POLLIN)
                {
                    char buf[1024] = {0};
                    int len = recv(fd, buf, sizeof(buf), 0);
                    if (len == -1)
                    {
                        perror("recv error");
                        exit(1);
                    }
                    else if (len == 0)
                    {
                        printf("客户已经断开连接\n");
                        allfd[i].fd = -1;
                        close(fd);
                    }
                    else
                    {
                        printf("recv buf = %s\n",buf);
                        for (int j=0; j<len; j++)
                        {
                            buf[j] = toupper(buf[j]);
                        }
                        send(fd, buf, strlen(buf)+1, 0);
                    }
                }
            }
        }
        close(lfd);
        return 0;
    }
    

     

     

    epoll 水平触发模式

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <sys/epoll.h>
    #include <arpa/inet.h>
    #include <ctype.h>
    
    int main(int argc, char **argv)
    {
        int lfd;
        int ret;
        struct sockaddr_in server, client;
        socklen_t client_len;
    
        lfd = socket(AF_INET, SOCK_STREAM, 0);
        if (lfd == -1)
        {
            perror("socket error");
            exit(1);
        }
        //绑定服务器地址信息
        server.sin_family = AF_INET;
        server.sin_port   = htons(6666);
        server.sin_addr.s_addr = htonl(INADDR_ANY);
        ret = bind(lfd, (struct sockaddr *)&server, sizeof(server));
        if (ret == -1)
        {
            perror("bind error");
            exit(1);
        }
        //设置监听上限
        ret = listen(lfd, 128);
        if (ret == -1)
        {
            perror("listen error");
            exit(1);
        }
        //开始epoll的相关设置
        //创建epoll树
        int epfd = epoll_create(2000);
        struct epoll_event ev;
        ev.events = EPOLLIN;
        ev.data.fd = lfd;
        epoll_ctl(epfd, EPOLL_CTL_ADD, lfd, &ev);
    
        struct epoll_event all[2000];
        while (1)
        {
            //使用epoll通知内核IO检测
            ret = epoll_wait(epfd, all, sizeof(all)/sizeof(all[0]), -1);
            //遍历数组中的前ret个元素
            for (int i=0; i<ret; i++)
            {
                int fd = all[i].data.fd;
                if (fd == lfd)
                {
                    client_len = sizeof(client);
                    //接受连接请求
                    int cfd = accept(lfd, (struct sockaddr *)&client, &client_len);
                    if (cfd == -1)
                    {
                        perror("accept error");
                        exit(1);
                    }
                    //将新连接的客户端cfd挂到树上
                    struct epoll_event temp;
                    temp.events = EPOLLIN;
                    temp.data.fd = cfd;
                    epoll_ctl(epfd, EPOLL_CTL_ADD, cfd, &temp);
                    //打印ip信息
                    char ip[64];
                    printf("new client ip:%s,port%d\n",
                            inet_ntop(AF_INET, &client.sin_addr.s_addr, ip, sizeof(ip)),
                            ntohs(client.sin_port));
                }
                else
                {
                    //客户端数据发送过来
                    if (!all[i].events & EPOLLIN)
                    {
                        continue;
                    }
                    char buf[1024] = { 0 };
                    int len = recv(fd, buf, sizeof(buf), 0);
                    if (len == -1)
                    {
                        perror("recv error");
                        exit(1);
                    }
                    else if (len == 0)
                    {
                        printf("客户端断开连接\n");
                        ret = epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL);
                        if (ret == -1)
                        {
                            perror("epoll_ctl error");
                            exit(1);
                        }
                        close(fd);
                    }
                    else
                    {
                        printf("recv buf:%s\n", buf);
                        write(fd, buf, len);
                    }
                }
            }
        }
        close(lfd);
        return 0;
    }
    

     

    展开全文
  • C语言链接TCP服务器: 核心代码采用epoll监听回调的方式实现,核心代码就是link.hlink.c,基本架构如下: 由于TCP是流式数据,因此收到数据后我们通过Parser解析一个完整的报文,比如...

    新建一个物联网行业交流学习QQ群,感兴趣可加:928840648

    代码目录树:

        纯C语言编程只需要两个核心文件: link.h  link.c 即可;C++架构的程序需要用到 link.h link.c还有linker.h linker.cpp,后者是在前者的基础上做了封装。

    接口的使用如下,TCP创建服务器代码:

    如果是C语言:

    C语言链接TCP服务器:

    核心代码采用epoll监听回调的方式实现,核心代码就是link.h和link.c,基本架构如下:

    由于TCP是流式数据,因此收到数据后我们通过Parser解析一个完整的报文,比如Json报文,然后link再调用handler回调到用户层,用户处理具体的业务逻辑。

    C++接口如下:

    我们可以继承linker,然后重写packet和handle函数。

    C语言接口如下:

    link_init在最开始调用,link_release在进程退出前调用;link采用id进行管理,要创建一个server或者client,首先需要alloc一个id出来,再进行创建/链接。

    我们可以创建TCP服务器,也可以创建unix-socket(本地套接字)的服务器。

    连接的API如上。

    轮询API有两个,如果你的框架有只要基于TCP/Unix-Socket实现,那么建议调用link_loop_forever;如果你的主框架只是需要一个TCP服务或者客户端,建议定时频繁地调用link_loop。

    新建一个物联网行业交流学习QQ群,感兴趣可加:928840648

    应用实例及源码可以参考:rk3308应用篇 —— Linux 串口异步I/O框架

    展开全文
  • 基于 TCP协议 的网络编程一般分为服务器和客户端两部分,常见的核心步骤和流程如下: 客户端篇: connect()函数 对于客户端的 connect() 函数,该函数的功能为客户端主动连接服务器,建立连接是通过三次握手,...
  • TCP服务器和客户端交互

    千次阅读 2015-08-17 10:52:19
    学习掌握Linux下的TCP服务器基本原理基本编程方法,体会TCP与UDP编程的不同,UDP编程:http://blog.csdn.net/yueguanghaidao/article/details/7055985 二、实验平台 Linux操作系统 三、实验内容 编写...
  • 总体需求:编写tcp文件服务器和客户端。客户端可以上传和下载文件。================================================分解需求客户端功能描述:1)要求支持以下命令:help: 显示客户端所有命令和说明, 在本地实现...
  • //创建监听服务器 struct evconnlistener *evl = evconnlistener_new_bind(base, listen_cb, base, LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, -1, (struct sockaddr*)&serv_addr, sizeof...
  • 利用TCP网络通信实现客户端和服务器的通信 服务器代码 server.c #include<stdio.h> #include<sys/socket.h> #include<sys/types.h> #include<string.h> #include<unistd.h> #include&...
  • linux网络编程,其实指的就是socket编程,下面仅记下自己对socket的理解。1. socket介绍 socket又叫套接字,在linux中,一切皆文件,socket其实也就是...常用的socket编程一般分TCP和UDP两种: TCP(Transmission...
  • Linux环境下TCP服务器和客户端的搭建 接下来需要完成客户端与服务器的相互通信。 在上文中,是通过read/write来实现读取数据和发送数据的,要同时实现收与发,是否将read ,write都加在客户端和服务器就可以了呢? 来...
  • Linux下创建一个tcp服务器,有以下六个步骤: socket – 创建套接字 bind – 绑定主机端口 listen --设置监听套接字 accept – 接收客户端连接,并生成新的套接字 read/write – 收发数据 close – 关闭套...
  • 在对TCP服务器客户端的工作原理进行剖析后,又进一步了解了网络编程需要的函数等,为了更深的熟悉TCP数据交互流程,于是在Linux环境下对其代码进行仿写。在编写程序前对其涉及到的一些知识进行一个了解。然后再贴...
  • https://blog.csdn.net/qq_40194498/article/details/80245607 https://blog.csdn.net/qq_40194498/article/details/80242662
  • 总体需求:编写tcp文件服务器和客户端。客户端可以上传和下载文件。 ================================================ 分解需求 客户端功能描述: 1)要求支持以下命令:help: 显示客户端所有命令和...
  • 一、实验目的 学习和掌握Linux下的TCP服务器基本原理和基本编程方法 二、实验平台 ...使用TCP套接字编程可以实现基于TCP/IP协议的面向连接的通信,它分为服务器端和客户端两部分,其主要实现过程
  • /***功能:创建套接字同时指定协议类型*#include <sys/socket.h>*family(协议簇): AF_INET(IPv4协议) AF_INET6(IPv6协议)*type(套接字类型):SOCK_STREAM(流式套接字) TCP通信使用 SOCK_DGRAM(数据报...
  • Linux下编写UDP/TCP版本的服务器和客户端的流程 一:UDP和TCP的区别 1、TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接 2、TCP提供可靠的服务。也就是说,通过TCP连接传送...
  • 前面几篇中实现的client每次运行只能从命令行读取一个字符串发给服务器,再从服务器收回来,现在我们把它改成交互式的,不断从终端接受用户输入并server交互。 /* client.c */ #include #include #include #...
  • 1,TCP服务器流程 服务器: (1)创建socket,使用socket函数 (2)准备通信地址,使用结构体类型 (3)绑定socket通信地址,使用bind函数 (4)进行通信,使用read/write函数 (5)关闭socket,使用close函数 客户端...
  • Linux Tcp客户端和服务器端代码实现

    千次阅读 2015-07-30 23:59:22
    1、int socket(int domain, int type, int protocol);函数解析功能:创建socket,也就是创建一个socket... type: 服务类型,主要有SOCK_STREAM流服务(TCP协议使用),SOCK_DGRAM数据报服务(UDP协议使用)  protoc
  • Linux下网络编程TCP客户端和服务器端数据传输代码的实现,c语言程序,使用前请阅读readme.txt
  • LinuxTCP客户端和服务器代码编写

    千次阅读 2015-10-16 08:39:30
    一、各部分功能: 服务器:主动建立服务程序,等待客户端连接,相应客户端的请求 ...3、最后写客户端和服务器通信的语句。 三、先写服务器程序,然后用telnet 模拟客户端远程登录 1、socket int sock
  • //tcpserver.c #include #include #include #include #include #include #include #include #include #include #include #include int main(){  int sockfd,clifd;...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,775
精华内容 710
关键字:

linuxtcp服务器和客户端

linux 订阅