socket编程(2)—— 一对多通信

原创 2016年08月30日 15:59:27

1 一对多模型,TCP的编程步骤

服务端:
1、socket()获得一个sockfd。注意第二个参数必须SOCK_STREAM.
2、准备通信地址(必须服务器的)
3、bind()绑定。(开放了端口,允许客户端连接)
4、监听客户端 listen()函数
5、等待客户端的连接 accept(),返回用于交互的socket描述符
6、使用第5步返回sockt描述符,进行读写通信。
7、关闭sockfd。

客户端:
客户端的代码与一对一的一样。注意第二个参数必须SOCK_STREAM.

TCP一对多模型,有两类描述符:
第一步的描述符不再参与信息交互,只是等待客户端的连接(accept),accept()在客户端连接上来后,会返回一个新的描述符,用于读写通信。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>

int main(){
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    if (sockfd == -1){
        perror("socket"),exit(-1);
    }

    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(2222);
    addr.sin_addr.s_addr = inet_addr("192.168.66.11");
    int res = bind(sockfd,(struct sockaddr*)&addr,
            sizeof(addr));
    if (res == -1){
        perror("bind"),exit(-1);
    }
    printf("bind ok\n");

    listen(sockfd,100);//监听

    struct sockaddr_in client;
    socklen_t len = sizeof(client);
    int fd = accept(sockfd,(struct sockaddr*)&client,&len);
    char *from = inet_ntoa(client.sin_addr);//十六进制转点分十进制
    printf("%s连接成功\n",from);
    char buf[100] = {};
    res = read(fd,buf,sizeof(buf));
    printf("接受了%d字节,内容:%s",res,buf);
    write(fd,"welcome",7);
    close(fd);
    close(sockfd);
    return 0;
}
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>

int main(){
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    if (sockfd == -1){
        perror("socket"),exit(-1);
    }

    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(2222);//连接端口
    addr.sin_addr.s_addr = inet_addr("192.168.66.11");//都是服务器的,改成连接IP
    int res = connect(sockfd,(struct sockaddr*)&addr,
            sizeof(addr));
    if (res == -1){
        perror("connect"),exit(-1);
    }
    printf("连接成功\n");
    write(sockfd,"hello",5);
    char buf[100] = {};
    res = read(sockfd,buf,sizeof(buf));
    printf("读到了%d字节,内容:%s\n",res,buf);
    close(sockfd);
    return 0;
}

上面的服务端还只是实现了一对一的通信,一对多通信加一个while循环即可。

2 练习

1、在客户端加上输入功能,允许发送不同的信息,并且客户端和服务器端代码要支持多次输入和输出(读写上加循环),输入bye退出。客户端发送的内容改为输入,服务器发回给客户端的内容改成客户端的输入。

2、可以考虑在服务器端启动多进程fork(),支持多个客户端的并行。

server.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<signal.h>

int sockfd;
void fa(int signo){
    printf("服务器正在关闭\n");
    sleep(1);
    close(sockfd);
    exit(0);
}
int main(){
    printf("ctrl+c退出服务器\n");
    signal(SIGINT,fa);
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    if (sockfd == -1){
        perror("socket"),exit(-1);
    }

    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(2222);
    addr.sin_addr.s_addr = inet_addr("192.168.66.11");

    int reuseaddr = 1;//解决地址已被占用问题
    setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,
            &reuseaddr,sizeof(reuseaddr));

    int res = bind(sockfd,(struct sockaddr*)&addr,
            sizeof(addr));
    if (res == -1){
        perror("bind"),exit(-1);
    }
    printf("bind ok\n");
    listen(sockfd,100);//监听
    while (1){
        struct sockaddr_in client;
        socklen_t len = sizeof(client);
        int fd = accept(sockfd,(struct sockaddr*)&client,
                &len);//阻塞函数
        char *from = inet_ntoa(client.sin_addr);
        printf("%s连接成功\n",from);
        pid_t pid = fork();
        if (pid == 0){
        char buf[100] = {};
        while (1){
            res = read(fd,buf,sizeof(buf));
            printf("接受了%d字节,内容:%s\n",res,buf);
            if (res <= 0){//包括0和-1
                break;
            }
            if (strcmp(buf,"bye") == 0){
                break;
            }
            write(fd,buf,strlen(buf));
            memset(buf,0,sizeof(buf));
        }
        close(fd);
        exit(0);
        }
    close(fd);
    }
}
client.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>

int main(){
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    if (sockfd == -1){
        perror("socket"),exit(-1);
    }

    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(2222);//连接端口
    addr.sin_addr.s_addr = inet_addr("192.168.66.11");//都是服务器的,改成连接IP
    int res = connect(sockfd,(struct sockaddr*)&addr,sizeof(addr));
    if (res == -1){
        perror("connect"),exit(-1);
    }
    printf("连接成功\n");

    char buf[100] = {};
    while (1){
        memset(buf,0,sizeof(buf));//buf清0
        printf("请输入要说的话\n");
        scanf("%s",buf);
        write(sockfd,buf,strlen(buf));
        if (strcmp(buf,"bye") == 0){//退出的合适位置
            break;
        }
        memset(buf,0,sizeof(buf));//buf清0
        res = read(sockfd,buf,sizeof(buf));
        printf("读到了%d字节,内容:%s\n",res,buf);
    }

    close(sockfd);
    return 0;
}
版权声明:本文为博主原创文章,遵循GPL协议精神,转载请注明出处。

相关文章推荐

socket实现多个客户端连接在一个服务器上

1、使用socekt通信一般步骤     1)服务器端:socker()建立套接字,绑定(bind)并监听(listen),用accept()等待客户端连接。     2)客户端:socker()...

关于socket一对一和多对一连接总结

一个客户端对应一个服务端长连接: while(true)应该在输入输出流方位进行阻塞,目的指accept阻塞一个客户端,并进行长连接处理客户端信息,此时客户端服务端都不可断开; 多个客户端...

Java Socket实现多个客户端连接同一个服务端

使用Socket实现多个客户端和同一客户端通讯;首先客户端连接服务端发送一条消息,服务端接收到消息后进行处理,完成后再回复客户端一条消息。本人通过自己的思维编写了一份服务端和客户端实现的代码,望能与大...

socket一个多线程多客户端即时聊天学习

转载: 1.Socket是代表两台机器之间网络连接的对象(java.net.Socket)。    Socket的建立如下,参数分别是服务器端的IP地址和端口号: Socket...

Windows Socket 编程_单个服务器对多个客户端简单通讯

单个服务器对多个客户端程序: 一。简要说明 二。查看效果 三。编写思路 四。程序源代码 五。存在问题   一。简要说明:  程序名为:TcpSocketOneServerToMulCl...

Socket编程(二)随时接收客户端消息及多客户端连接

使服务器具有随时接收消息的能力 使用类似于心跳包的方法进行测试 SocketClient import java.io.BufferedReader; import java.io.Bu...

网络编程学习笔记一:Socket编程

“一切皆Socket!” 话虽些许夸张,但是事实也是,现在的网络编程几乎都是用的socket。 ——有感于实际编程和开源项目研究。 我们深谙信息交流的价值,那网络中进程之间如何通信,如我们每天打...

Java 网络编程(TCP)实现服务器与客户端1对多的随意顺 序的聊天室

要求:任何一个客户端说的任何一句话,都会转发给所有客户端,(并在服务器端记录在聊天文件中,包括聊天时间信息.服务器只转发,不参与聊天.) (每一个参与聊天的客户端要有自己的名字.在进入聊天室的时候输...

Linux网络编程——tcp并发服务器(poll实现)

想详细彻底地了解poll或看懂下面的代码请参考《Linux网络编程——I/O复用之poll函数》 代码: #include #include #include #include #incl...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)