telnet.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <time.h>
#include <stdarg.h>
#define ERR_EXIT(m, ...) \
do { \
fprintf(stderr, m"\n", ##__VA_ARGS__); \
log(m"\n", ##__VA_ARGS__); \
exit(EXIT_FAILURE); \
} while (0)
#define MAX_BUFF_LEN 1024
void log(const char *fmt, ...)
{
char buffer[MAX_BUFF_LEN] = {0};
va_list args;
time_t timep;
time(&timep);
struct tm *p = gmtime(&timep);
FILE* fp = fopen("telnet.log", "a+");
if(fp){
snprintf(buffer, MAX_BUFF_LEN, "[%.4d-%.2d-%.2d %.2d:%.2d:%.2d][%d]", (1900+p->tm_year),(1+p->tm_mon), p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec, getpid());
va_start(args, fmt);
vsnprintf(buffer + strlen(buffer), MAX_BUFF_LEN - strlen(buffer) - 1, fmt, args);
va_end(args);
fwrite(buffer, strlen(buffer), 1, fp);
fclose(fp);
}
}
ssize_t /* Write "n" bytes to a descriptor. */
writen(int fd, const void *vptr, size_t n){
size_t nleft;
ssize_t nwritten;
const char *ptr;
ptr = vptr;
nleft = n;
while (nleft > 0) {
if ( (nwritten = write(fd, ptr, nleft)) <= 0) {
if (nwritten < 0 && errno == EINTR)
nwritten = 0; /* and call write() again */
else
return(-1); /* error */
}
nleft -= nwritten;
ptr += nwritten;
}
return(n);
}
int main(int argc,char **argv){
if(argc < 3){
fprintf(stderr, "Usage: %s ServerIPAddress ServerPort\n",argv[0]);
return 0;
}
fd_set rset;
FD_ZERO(&rset);
int sock = socket(AF_INET,SOCK_STREAM,0);
struct sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET; //internet协议族
struct hostent *h = gethostbyname(argv[1]);
server_addr.sin_addr = *((struct in_addr *)h->h_addr);
server_addr.sin_port = htons(atoi(argv[2]));
if(connect(sock,(struct sockaddr*)&server_addr, sizeof(struct sockaddr_in)) < 0){
ERR_EXIT("connect to %s:%s failed", argv[1], argv[2]);
}
fprintf(stdout, "% 9d\n", getpid());
fflush(stdout);
int nready;
int maxfd;
int fd_stdin = fileno(stdin);
int fd_stdout = fileno(stdout);
if (fd_stdin > sock)
maxfd = fd_stdin;
else
maxfd = sock;
char sendbuf[1024*4] = {0};
char recvbuf[1024*4] = {0};
while (1){
FD_SET(fd_stdin, &rset);
FD_SET(sock, &rset);
nready = select(maxfd + 1, &rset, NULL, NULL, NULL); //select返回表示检测到可读事件
if (nready == -1) ERR_EXIT("select error");
if (nready == 0) continue;
if (FD_ISSET(sock, &rset)){
int ret = read(sock, recvbuf, sizeof(recvbuf)); //按行读取
if (ret == -1) ERR_EXIT("read from socket error");
else if (ret == 0) ERR_EXIT("server close"); //服务器关闭
writen(fd_stdout, recvbuf, ret);
memset(recvbuf, 0, sizeof(recvbuf));
}
if (FD_ISSET(fd_stdin, &rset)){
int ret = read(fd_stdin, sendbuf, sizeof(sendbuf));
if(ret > 0) {
writen(sock, sendbuf, ret);
memset(sendbuf, 0, sizeof(sendbuf));
}else{
ERR_EXIT("read from stdin error");
}
}
}
close(sock);
exit(0);
}
编译方法:
gcc -o telnet telnet.c