|
![]() | 作者: tetley [tetley]
![]() |
登录 |
我想编一个群体聊天的东西,就像是QQ中的群。 我的想法是在一个公用主机上运行一个服务端, 服务端每接到一个连接请求就将以联上的客户端的IP地址放到一个自建的IP地指表中, 并且创建一个新线程, 用来接收信息,而且在同一新线程中按照IP地址表中的IP地址再创建多个SOCKET连接将收到的信息广播给各个客户端。主线程用一个循环来接受下一个连接。 客户端创建两个SOCKET, 一个绑定固定端口用来接收广播, 另一个用来发送信息给服务端。用不同线程实现, 在线程中用循环已接受多个信息。 各位说说我的想法对不对呢? [此贴被 黑雨(tetley) 在 02月25日07时13分 编辑过] [此贴被 天空(tetley) 在 03月05日18时49分 编辑过] [此贴被 天空(tetley) 在 03月05日18时50分 编辑过] ![]() [此贴被 天空(tetley) 在 03月11日05时30分 编辑过] |
地主 发表时间: 04-02-25 07:04 |
![]() | 回复: fox [farfox] ![]() |
登录 |
你还需要考虑多个客户端共用IP的情况,经常有通过代理的好多人用同一个IP |
B1层 发表时间: 04-02-25 11:55 |
![]() | 回复: tetley [tetley] ![]() |
登录 |
我想先做个简单的, 然后再考虑其他的情况。 大家说说 是不是这个思路呀 |
B2层 发表时间: 04-02-25 19:56 |
![]() | 回复: tetley [tetley] ![]() |
登录 |
客户端 #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> void error(char *msg) { perror(msg); exit(0); } int main(int argc, char* argv[]) { int sockfd; struct sockaddr_in serv_addr; struct hostent *server; char buffer[256]; int portno; int sersockfd, newsockfd; struct sockaddr_in serv, cli; int clilen; char temp[256]; portno = atoi(argv[2]); //设置发射端 server = gethostbyname(argv[1]); bzero((char *)&serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(portno); bcopy((char *)server->h_addr, (char *)&serv_addr, sizeof(serv_addr)); bzero((char *)&serv, sizeof(serv)); //设直接收端 serv.sin_family = AF_INET; serv.sin_addr.s_addr = INADDR_ANY; serv.sin_port = htons(atoi("12345")); if( fork() == 0 ) //在子线程中进行监听 { sersockfd = socket(AF_INET, SOCK_STREAM, 0); if( sersockfd < 0 ) error("Error on creating sersockfd"); if(bind( sersockfd, (struct sockaddr *)&serv, sizeof(serv) ) < 0) error("Error on binding"); listen(sersockfd, 5); clilen = sizeof(cli); while(1) { newsockfd = accept(sersockfd, (struct sockaddr *)&cli, &clilen); if( newsockfd < 0 ) error("Error on accepting"); if( fork() == 0 ) { bzero(temp, 255); close(sersockfd); read(newsockfd, temp, 255); printf(" the Message receiving is %s \n", temp); close(newsockfd); exit(1); } close(newsockfd); } } sockfd = socket(AF_INET, SOCK_STREAM, 0); //在主线程中进行fgets和发送到服务端。 if( sockfd < 0 ) error(" Error on creating sockfd"); while(1) { if( fork() == 0) { bzero(buffer, 256); printf("Enter the Message->"); fgets(buffer, 255, stdin); if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0 ) error("Error on connecting"); printf("after connecting! \n"); write(sockfd, buffer, strlen(buffer)); close(sockfd); exit(1); } } return 0; } [此贴被 天空(tetley) 在 03月06日06时08分 编辑过] |
B3层 发表时间: 04-03-04 21:23 |
![]() | 回复: tetley [tetley] ![]() |
登录 |
服务端 #include<stdio.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #include<netdb.h> void error(char *msg) { printf(msg); exit(1); } int main(int argc, char *argv[]) { int portno, sockfd, newsockfd; char buffer[256]; struct sockaddr_in serv_addr, cli_addr; int clilen, n, i; char temp[256]; char *tempip; if(argc > 2) { error("too many argc\n"); exit(1); } if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) <= 0) //设置服务端的监听socket. error("wrong on creating socket"); bzero((char*) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; portno = atoi(argv[1]); serv_addr.sin_port = htons(portno); if((i = bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr))) < 0) { error("wrong on binding\n"); } listen(sockfd, 5); printf("listening.....\n"); while(1) { clilen = sizeof(cli_addr); newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen); //如果接到连接请求, 建一个新线程, 进行接受数据和广播 printf("after accept\n"); tempip = inet_ntoa(cli_addr.sin_addr); //创建ip表,以便实行广播, 还没弄完。 if( fork() == 0 ) //在子线程中 { close(sockfd); read(newsockfd, buffer, 255); //读数据 printf("the message is from %s is -->%s \n", inet_ntoa(cli_addr.sin_addr), buffer); close(newsockfd); sockfd = socket(AF_INET, SOCK_STREAM, 0); //创建发送口, 用来广播。可能不叫广播, 先这么叫吧, 理解就行了。 bzero((char*) &cli_addr, sizeof(cli_addr)); //如果有ip表, 就创建多个sockaddr 进行广播。 现在先用一个代替 cli_addr.sin_family = AF_INET; cli_addr.sin_addr.s_addr = inet_addr(tempip); cli_addr.sin_port = htons(atoi("12335")); printf("connecting to .....%s\n", tempip); if(connect(sockfd, (struct sockaddr *)&cli_addr, sizeof(cli_addr)) < 0) //联到客户端。 error("Error on connecting.....:\n"); printf("sending message..... %s\n", buffer); write(sockfd, buffer, 255); //广播信息 printf("finished sending.....\n"); close(sockfd); exit(1); } close(newsockfd); } } [此贴被 天空(tetley) 在 03月06日06时14分 编辑过] |
B4层 发表时间: 04-03-04 21:24 |
![]() | 回复: tetley [tetley] ![]() |
登录 |
谁能帮我看看怎么回事呀 , 客户端怎么老是循环不停。 在 fget时 应该能暂停线程, 但它只是越过fget, 进行connect, 而且connect 老是连接不成功。谁能帮我看看呀。 我没有加ip 表进行广播收到的信息, 客户端和服务端 测试时用的同一台主机, 所以没加ip 表。 [此贴被 天空(tetley) 在 03月04日21时30分 编辑过] |
B5层 发表时间: 04-03-04 21:27 |
![]() | 回复: tetley [tetley] ![]() |
登录 |
大家来看看呀, 我每次运行时客户端都联不上服务端, 因为客户端等待输入时没有pause 线程, connect 失败。怎么回事呢? |
B6层 发表时间: 04-03-05 18:54 |
![]() | 回复: ghame [ghame] ![]() |
登录 |
加些注释吧.程序比较长,看到后面前面的变量是代表什么都忘记了. 通俗易懂别人才好帮你啊. |
B7层 发表时间: 04-03-06 00:56 |
![]() | 回复: tetley [tetley] ![]() |
登录 |
已经写完注释了。 大家帮忙看看。![]() |
B8层 发表时间: 04-03-06 06:18 |
![]() | 回复: tetley [tetley] ![]() |
登录 |
自己顶一下, 大家帮忙看看, 急。![]() |
B9层 发表时间: 04-03-08 18:46 |
|
20CN网络安全小组版权所有
Copyright © 2000-2010 20CN Security Group. All Rights Reserved.
论坛程序编写:NetDemon
粤ICP备05087286号