以前好像用过telnet的聊天室,现在很少见有人玩这个了,基本上都用网页或者图形界面的程序登录聊天。今天简单地写了一个telnet的服务器程序。虽然代码很简短,但能支持多个人同时连接,可以扩展为一些使用的程序,例如聊天、游戏、控制等。通过特殊的控制字符,还可以让telnet输出有颜色的字符。通过按一定的帧速输出字符,可以作成视频,例如气泡熊的badapple。
欢迎 telnet xiaoxia.org 2010
废话少说,上代码:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netdb.h> #define MAX_CONNECTIONS 100 struct connection { int sockfd; int pos; }conns[MAX_CONNECTIONS]={0}; char* dispstr = "\ Loading . . . .\r\n\r\n\ *************************************\r\n\ What to say? \r\n\ *************************************\r\n\ (EOF)\r\n"; static void closeconn(int i) { shutdown(conns[i].sockfd, SHUT_RD); close(conns[i].sockfd); conns[i].sockfd = 0; printf("closeconn %d\n", i); } int main(int argc, char **argv) { fd_set fdreads; struct timeval tv; int i, ret, displen = strlen(dispstr); int sock = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP ); /* reuse the network port */ ret = 1; setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*)&ret, sizeof(ret)); struct sockaddr_in addr = { 0 }; addr.sin_family = PF_INET; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_port = htons( 2010 ); if ( bind( sock, (struct sockaddr*)&addr, sizeof(struct sockaddr_in) ) < 0 ) { perror("failed to bind socket"); return(1); } listen( sock , 5); printf("telserver socket is listening.\n"); for (;;) { tv.tv_sec=0; tv.tv_usec=1000*200; FD_ZERO(&fdreads); FD_SET(sock, &fdreads); for (i=0; i<MAX_CONNECTIONS; i++) if (conns[i].sockfd) { do { if (send(conns[i].sockfd, dispstr + conns[i].pos ++, 1, 0) <= 0 ) { closeconn(i); break; } } while (!iscntrl(dispstr[conns[i].pos]) && !isspace(dispstr[conns[i].pos]) && conns[i].pos<displen); if (conns[i].pos>=displen) closeconn(i); } ret = select( MAX_CONNECTIONS+1, &fdreads, 0, 0, &tv ); switch (ret) { case -1: perror("select error"); break; case 0: /* timeout */ break; default: if (FD_ISSET(sock, &fdreads)) { for (i=0; i<MAX_CONNECTIONS; i++) if (!conns[i].sockfd) break; if (i!=MAX_CONNECTIONS) { conns[i].sockfd = accept(sock, 0, 0); conns[i].pos = 0; printf("openconn %d\n", i); } } } } return 0; }
看不懂,纯支持
@Xiaoxia,我也去玩玩
telnet http://www.xiaoxia.org 2010 这个代码怎么写的?
不是已经给出代码了吗?
气泡熊那个:http://xiaoxia.org/2456.html
@Xiaoxia, 可以整个MUD,呵呵!
干嘛不多线程呢?不过用了select方式。。要是这样的话,不知要没有做压力测试,连接数多少?
呃。。。没做过压力测试。连接数多了,select肯定没优势。传统的多线程也是。