以前好像用过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肯定没优势。传统的多线程也是。