2020-11-02

开源伟大基于socket的网络聊天室

socket编程的话题早就如雷贯耳 ,我真不希望大家都用这种编程技术去搞什么黑客
互联网是平行的一个世界
我们可以一无所有
我们有我们的理想和未来
继续保持一种开放开源公益的姿态去服务社会
据我所知 这种socket编程技术 非常适合些连锁企业的
他们没多少技术 但有这方面的需求
有获取客户的需求 有管理客户的需求 有向客户展示的需求
但是他们些小企业 却没办法像大公司那样去架设一个大型网站
然后去维护他们怎么办
一种基于互联网的革命 必须要开始 重新谱写新的篇章
这将是一场技术上的革新
socket 这种开源的 友好的 源代码完全开放的方式 提供了个解决基础方案
但是还是有个棘手的问题
我们在网络上交流必须要有个IP跟端口的
我们可以基于技术上的努力 不需要服务器
这也让我们失去了个统一协调的机制
怎么样才能让我们的产品不需要服务器 但是我们又能保持正常的相互通讯状态呢
就目前状态 我想到的解决方案是 利用网络硬盘
首先打开网络硬盘 我这里是百度硬盘
打开https://pan.baidu.com/网址账户15255663685密码sun881213如需验证码call电话查询IP资源
在这里面我把我申请的硬盘空间作为公共资源 大家都可以查阅
然后大家打开这个强烈建议打开http://xzc.cn/uUuKIeB52Z网址提交个人姓名及IPTXT
这个网址不需要大家注册 就可以直接提交文件到刚才我们打开的网络硬盘
然后我们可以利用获取的IP资源相互通讯 用我们的开源socket
怎么掐 都行
因为 它开源 所以 它好玩 因为它 开源 所以我们怎么玩都可以
下面是 Windows 下visal studio2019 环境下的用C语言写的socket聊天基本框架
这个界面不友好 还有好多东西优化下 我的想法是
socket已经很好;
只是我们还需要优化下 到普罗大众都可以轻松使用的地步

这是客户端代码

 /*
    Create a TCP socket
*/
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<winsock2.h>
 
#pragma comment(lib,"ws2_32.lib") //Winsock Library
 
int main(int argc , char *argv[])
{
    WSADATA wsa1;
    char* hostname = "localhost";
    char ip[100];
    struct hostent* hostEntry;
    struct in_addr** addr_list;
    int i;

    printf("\nInitialising Winsock...");
    if (WSAStartup(MAKEWORD(2, 2), &wsa1) != 0)
    {
        printf("Failed. Error Code : %d", WSAGetLastError());
        return 1;
    }

    printf("Initialised.\n");


    if ((hostEntry = gethostbyname(hostname)) == NULL)
    {
        //gethostbyname failed
        printf("gethostbyname failed : %d", WSAGetLastError());
        return 1;
    }

    //Cast the h_addr_list to in_addr , since h_addr_list also has the ip address in long format only
    addr_list = (struct in_addr**)hostEntry->h_addr_list;

    for (i = 0; addr_list[i] != NULL; i++)
    {
        //Return the first one;
        strcpy(ip, inet_ntoa(*addr_list[i]));
    }

    printf("%s resolved to : %s\n", hostname, ip);
    //以上查询本地IP
    WSADATA wsa;
    SOCKET s;
    struct sockaddr_in server;
    char *message , server_reply[2000];
    int recv_size;
 
    printf("\nInitialising Winsock...");
    if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
    {
        printf("Failed. Error Code : %d",WSAGetLastError());
        return 1;
    }
     
    printf("Initialised.\n");
     
    //Create a socket
    if((s = socket(AF_INET , SOCK_STREAM , 0 )) == INVALID_SOCKET)
    {
        printf("Could not create socket : %d" , WSAGetLastError());
    }
 
    printf("Socket created.\n");
    printf("强烈建议打开https://pan.baidu.com/网址账户15255663685密码sun881213如需验证码call电话查询IP资源\n");
    printf("强烈建议打开http://xzc.cn/uUuKIeB52Z网址提交个人姓名及IPTXT\n");
    server.sin_addr.s_addr = inet_addr("127.0.0.1");
    server.sin_family = AF_INET;
    server.sin_port = htons( 8888 );
 
    //Connect to remote server
    if (connect(s , (struct sockaddr *)&server , sizeof(server)) < 0)
    {
        puts("connect error");
        return 1;
    }
     
    puts("Connected");
     
    //Send some data发送请求
    message = "GET / HTTP/1.1 发送TCP 消息去IP 127.0.0.1\r\n\r\n";
    if( send(s , message , strlen(message) , 0) < 0)
    {
        puts("Send failed");
        return 1;
    }
    puts("Data Send\n");
     
    //Receive a reply from the server接收html文档
    if((recv_size = recv(s , server_reply , 2000 , 0)) == SOCKET_ERROR)
    {
        puts("recv failed");
    }
     
    puts("Reply received\n");
 
    //Add a NULL terminating character to make it a proper string before printing
    server_reply[recv_size] = '\0';
    puts(server_reply);
 
    return 0;
} 

这里是服务器的代码`

#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<winsock2.h>
 
#pragma comment(lib, "ws2_32.lib") //Winsock Library
 
int main(int argc , char *argv[])
{
    WSADATA wsa;
    SOCKET master , new_socket , client_socket[30] , s;
    struct sockaddr_in server, address;
    int max_clients = 30 , activity, addrlen, i, valread;
    char *message = "ECHO Daemon v1.0 \r\n";
     
    //size of our receive buffer, this is string length.
    int MAXRECV = 1024;
    //set of socket descriptors
    fd_set readfds;
    //1 extra for null character, string termination
    char *buffer;
    buffer =  (char*) malloc((MAXRECV + 1) * sizeof(char));
 
    for(i = 0 ; i < 30;i++)
    {
        client_socket[i] = 0;
    }
 
    printf("\nInitialising Winsock...");
    if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
    {
        printf("Failed. Error Code : %d",WSAGetLastError());
        exit(EXIT_FAILURE);
    }
     
    printf("Initialised.\n");
     
    //Create a socket
    if((master = socket(AF_INET , SOCK_STREAM , 0 )) == INVALID_SOCKET)
    {
        printf("Could not create socket : %d" , WSAGetLastError());
        exit(EXIT_FAILURE);
    }
 
    printf("Socket created.\n");
     
    //Prepare the sockaddr_in structure
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons( 8888 );
     
    //Bind
    if( bind(master ,(struct sockaddr *)&server , sizeof(server)) == SOCKET_ERROR)
    {
        printf("Bind failed with error code : %d" , WSAGetLastError());
        exit(EXIT_FAILURE);
    }
     
    puts("Bind done");
 
    //Listen to incoming connections
    listen(master , 3);
     
    //Accept and incoming connection
    puts("Waiting for incoming connections...");
     
    addrlen = sizeof(struct sockaddr_in);
     
    while(TRUE)
    {
        //clear the socket fd set
        FD_ZERO(&readfds);
  
        //add master socket to fd set
        FD_SET(master, &readfds);
         
        //add child sockets to fd set
        for (  i = 0 ; i < max_clients ; i++)
        {
            s = client_socket[i];
            if(s > 0)
            {
                FD_SET( s , &readfds);
            }
        }
         
        //wait for an activity on any of the sockets, timeout is NULL , so wait indefinitely
        activity = select( 0 , &readfds , NULL , NULL , NULL);
    
        if ( activity == SOCKET_ERROR )
        {
            printf("select call failed with error code : %d" , WSAGetLastError());
            exit(EXIT_FAILURE);
        }
          
        //If something happened on the master socket , then its an incoming connection
        if (FD_ISSET(master , &readfds))
        {
            if ((new_socket = accept(master , (struct sockaddr *)&address, (int *)&addrlen))<0)
            {
                perror("accept");
                exit(EXIT_FAILURE);
            }
          
            //inform user of socket number - used in send and receive commands
            printf("New connection , socket fd is %d , ip is : %s , port : %d \n" , new_socket , inet_ntoa(address.sin_addr) , ntohs(address.sin_port));
        
            //send new connection greeting message
            if( send(new_socket, message, strlen(message), 0) != strlen(message) )
            {
                perror("send failed");
            }
              
            puts("Welcome message sent successfully");
              
            //add new socket to array of sockets
            for (i = 0; i < max_clients; i++)
            {
                if (client_socket[i] == 0)
                {
                    client_socket[i] = new_socket;
                    printf("Adding to list of sockets at index %d \n" , i);
                    break;
                }
            }
        }
          
        //else its some IO operation on some other socket :)
        for (i = 0; i < max_clients; i++)
        {
            s = client_socket[i];
            //if client presend in read sockets            
            if (FD_ISSET( s , &readfds))
            {
                //get details of the client
                getpeername(s , (struct sockaddr*)&address , (int*)&addrlen);
 
                //Check if it was for closing , and also read the incoming message
                //recv does not place a null terminator at the end of the string (whilst printf %s assumes there is one).
                valread = recv( s , buffer, MAXRECV, 0);
                 
                if( valread == SOCKET_ERROR)
                {
                    int error_code = WSAGetLastError();
                    if(error_code == WSAECONNRESET)
                    {
                        //Somebody disconnected , get his details and print
                        printf("Host disconnected unexpectedly , ip %s , port %d \n" , inet_ntoa(address.sin_addr) , ntohs(address.sin_port));
                      
                        //Close the socket and mark as 0 in list for reuse
                        closesocket( s );
                        client_socket[i] = 0;
                    }
                    else
                    {
                        printf("recv failed with error code : %d" , error_code);
                    }
                }
                if ( valread == 0)
                {
                    //Somebody disconnected , get his details and print
                    printf("Host disconnected , ip %s , port %d \n" , inet_ntoa(address.sin_addr) , ntohs(address.sin_port));
                      
                    //Close the socket and mark as 0 in list for reuse
                    closesocket( s );
                    client_socket[i] = 0;
                }
                  
                //Echo back the message that came in
                else
                {
                    //add null character, if you want to use with printf/puts or other string handling functions
                    buffer[valread] = '\0';
                    printf("%s:%d - %s \n" , inet_ntoa(address.sin_addr) , ntohs(address.sin_port), buffer);
                    send( s , buffer , valread , 0 );
                }
            }
        }
    }
     
    closesocket(s);
    WSACleanup();
     
    return 0;
} 

网络聊天室 !!因为开源 所以好玩!
记住这点,任何想把socket写成闭源的 行动注定是 失败的!
我们要做的是怎么 让它更开源 开放
让它 更强大!!!
就怎么布局 让我们能彼此 快速共享IP
欢迎大家献谋献策!
如果解决了这一步!
一个崭新的 时代来临 也不为过!
因为 这是一个没有服务器 没有霸权的时代!我们都可以充当服务器 也都是客户端 我们都是内容的提供者 也是资源的利用者

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值