开源伟大基于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
欢迎大家献谋献策!
如果解决了这一步!
一个崭新的 时代来临 也不为过!
因为 这是一个没有服务器 没有霸权的时代!我们都可以充当服务器 也都是客户端 我们都是内容的提供者 也是资源的利用者