Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
/*
* u-pong.c -- UDP通信で受信したメッセージを返すサーバ
*
* 0.0: Dec. 14, 2021 by Dai ISHIJIMA
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define EOS '\0'
#define PORT 43210
#define BYE "BYE"
#define NDUMP 16
char *prog;
#define shift --argc; ++argv
/* strerrorを使ってエラー出力 */
void perrno()
{
fprintf(stderr, "%s: [%d] %s\n", prog, errno, strerror(errno));
}
/* 時間切れまで待つ */
int waitfor(int d, int sec)
{
int nfds;
fd_set readfds;
struct timeval timeout;
fcntl(d, F_SETFL, O_NONBLOCK);
FD_ZERO(&readfds);
FD_SET(d, &readfds);
timeout.tv_sec = sec;
timeout.tv_usec = 0;
/* 時間切れになるか、入力があるまで待つ (定型文) */
nfds = select(d + 1, &readfds, NULL, NULL, &timeout);
if ((nfds < 0) && (errno != EINTR)) {
fprintf(stderr, "%s: select failed\n", prog);
fprintf(stderr, "%s: %d %s\n", prog, errno, strerror(errno));
exit(1);
}
if ((nfds > 0) && (FD_ISSET(d, &readfds))) {
/* 時間切れ前に入力があった */
return(0);
}
/* 時間切れ */
fprintf(stderr, "%s: connection timed out\n", prog);
exit(1);
}
/* 16進でデータを表示する */
void dump(FILE *fp, int len, char *buf)
{
int i, j;
for (j = 0; j < len; j += NDUMP) {
fprintf(fp, "%04x ", j);
for (i = 0; (i < NDUMP) && (i + j < len); i++) {
if (i == NDUMP / 2) {
fprintf(fp, " ");
}
fprintf(fp, "%02x ", buf[i + j]);
}
for (; i < NDUMP; i++) {
if (i == NDUMP / 2) {
fprintf(fp, " ");
}
fprintf(fp, " ");
}
fprintf(fp, " ");
for (i = 0; (i < NDUMP) && (i + j < len); i++) {
if (i == NDUMP / 2) {
fprintf(fp, " ");
}
if ((' ' <= buf[i + j]) && (buf[i + j] < '~')) {
/* isprint(3) 案件 */
fprintf(fp, "%c", buf[i + j]);
}
else {
fprintf(fp, ".");
}
}
fprintf(fp, "\n");
}
}
/* UDPでメッセージを受信して返送する */
void udpong(int d, char *bye, int sec)
{
int len;
struct sockaddr_in caddr;
int clen;
char rbuf[BUFSIZ];
char sbuf[BUFSIZ];
struct timeval current;
for (;;) {
if (sec > 0) {
waitfor(d, sec);
}
clen = sizeof(caddr);
/* メッセージを受ける */
if ((len = recvfrom(d, rbuf, BUFSIZ - 1, 0,
(struct sockaddr *)&caddr,
(socklen_t *)&clen)) < 0) {
fprintf(stderr, "%s: no message\n", prog);
perrno();
exit(1);
}
gettimeofday(¤t, NULL);
rbuf[len] = EOS;
printf("[%s:%d] %d.%06d %s",
inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port),
(int)current.tv_sec, (int)current.tv_usec,
ctime((time_t *)¤t.tv_sec));
dump(stdin, len, rbuf);
sprintf(sbuf, "[%s:%d] %d.%6d, %s",
inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port),
(int)current.tv_sec, (int)current.tv_usec,
rbuf);
len = strlen(sbuf);
/* メッセージを返信する */
if (sendto(d, sbuf, len, 0,
(struct sockaddr *)&caddr, sizeof(caddr)) != len) {
fprintf(stderr, "%s: ", prog);
fprintf(stderr, "can't sendto() %d <- %s:%d\n",
d, inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port));
perrno();
exit(1);
}
if (strcmp(bye, rbuf) == 0) {
/* おしまいのメッセージならループを抜けて終了 */
break;
}
}
}
/* ソケットを初期化してディスクリプタ (記述子) を返す */
int initsocket(unsigned long a, unsigned short p)
{
int d;
struct sockaddr_in saddr;
/* UDP用のディスクリプタ (エンドポイント) を得る */
if ((d = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
fprintf(stderr, "%s: can't open socket\n", prog);
perrno();
exit(1);
}
/* 相手 (クライアント) のIPv4アドレスとポート */
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = a;
saddr.sin_port = htons(p);
if (bind(d, (struct sockaddr *)&saddr, sizeof(saddr)) != 0) {
fprintf(stderr, "%s: can't bind socket, %d <- %s:%d\n",
prog, d, inet_ntoa(saddr.sin_addr), p);
perrno();
exit(1);
}
return(d);
}
/* UDPサーバ */
void userver(unsigned long a, int p, char *bye, int sec)
{
int d;
d = initsocket(a, p);
udpong(d, bye, sec);
close(d);
}
void usage()
{
fprintf(stderr, "Usage: %s [-p #] [-a #.#.#.#] [-e BYE]\n", prog);
}
int main(int argc, char *argv[])
{
int p;
int a;
char bye[BUFSIZ];
int sec;
prog = *argv;
shift;
strcpy(bye, BYE);
p = PORT;
a = htonl(INADDR_ANY);
sec = 0;
while ((argc > 0) && (argv[0][0] == '-')) {
if (argv[0][1] == 'p') {
shift;
p = atoi(*argv);
}
else if (argv[0][1] == 'a') {
shift;
a = inet_addr(*argv);
}
else if (argv[0][1] == 'e') {
shift;
strcpy(bye, *argv);
}
else if (argv[0][1] == 't') {
shift;
sec = atoi(*argv);
}
else {
usage();
exit(1);
}
shift;
}
userver(a, p, bye, sec);
exit(0);
}
/* Local Variables: */
/* compile-command:"cc -Wall -o u-pong u-pong.c" */
/* End: */