-1
次のプログラムでは、サーバーを介して読み書きができます。しかし、書き込みを実行する()するとき、それは余分な文字をプリントアウトソケットから文字列を読み取っているときに、書き込みで余分な文字が出力される
// this a server program
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h> // for ssize_t data type
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include <arpa/inet.h>
#include <errno.h>
#include <wait.h>
#define LISTENQ (24) /* Backlog for listen() */
#define MAXBUFFSIZE 12
// Read in characters. Increase memory if we run out of space.
char *stdin_line(int conn)
{
int rr=0, size=0, cap = MAXBUFFSIZE;
char *str_ptr;//, oc;
char buff[MAXBUFFSIZE];
// allocate some memory for the pointer first
str_ptr = (char *) malloc(cap * sizeof(char));
assert(str_ptr != NULL);
// start reading from socket
rr=read(conn,buff,MAXBUFFSIZE)) > 0)
if(rr > 0){
str_ptr = buff;
size = MAXBUFFSIZE;
}
if(rr == -1) printf("Error (stdin_line): %s/n",strerror(errno));
return str_ptr;
}
void daemonize(void){
pid_t pid, sid=0;
// fork off process
pid = fork();
// failure
if(pid < 0){
printf("Error (fork<0): %s\n",strerror(errno));
exit(1);
}
// exit parent process
if(pid > 0){
printf("Error (fork>0): %s\n",strerror(errno));
exit(0);
}
// change file mode mask
umask(0);
// open log file for daemon debug information. OR as per requirements of hw4
// create new Session ID for child process
setsid();
if(sid < 0){
printf("Error (setsid<0): %s\n",strerror(errno));
exit(1);
}
// exit parent process
if(sid > 0){
printf("Error (setsid>0): %s\n",strerror(errno));
exit(0);
}
// change working directory to safe directory (one which is always there)
if(chdir("/") < 0){
printf("Error (chdir): %s\n",strerror(errno));
exit(1);
}
}
int main(void) {
int lstn_sock, conn_sock;
struct sockaddr_in my_serv;
short int pnum = 4080;
ssize_t wnum;
char *rstr=NULL;
// create listening socket
if((lstn_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("Error (socket): %s\n",strerror(errno));
exit(1);
}
// initialize socket address
memset(&my_serv, 0, sizeof(my_serv));
my_serv.sin_family = AF_INET;
my_serv.sin_addr.s_addr = INADDR_ANY;
my_serv.sin_port = htons(pnum);
// associate address with socket.
if(bind(lstn_sock, (struct sockaddr *) &my_serv, sizeof(my_serv)) < 0){
printf("Error (bind): %s\n",strerror(errno));
exit(1);
}
// start listening to socket
if(listen(lstn_sock, LISTENQ) < 0){
printf("Error (listen): %s\n",strerror(errno));
exit(1);
}
// make it a daemon
daemonize();
// work in the background
while(1){
// retrieve connect request and connect
if((conn_sock = accept(lstn_sock, NULL, NULL)) < 0){
printf("Error (accept): %s\n",strerror(errno));
exit(1);
}
rstr = stdin_line(conn_sock);
if((wnum=write(conn_sock,rstr,strlen(rstr))) <= 0){
printf("Error (write: rstr): %s\n",strerror(errno));
exit(1);
}
// close connected socket
if(close(conn_sock) < 0){
printf("Error (close): %s\n",strerror(errno));
exit(1);
}
}
return 0;
}
@ubuntu:$ ./my_code
@ubuntu:$ののtelnet localhostの4080
出力::: 1をしようと
。 ..
試行127.0.0.1 ..
ローカルホストに接続しました。
エスケープ文字は '^]'です。外部ホストによって閉じ
J
J
DHK
接続。
最初の「j」はユーザー(私)によって入力され、2番目の「j」はサーバーによってエコーされます。なぜ「dhk」と「9」の文字が得られますか?
ありがとう@ Tibor。実際には、read()から一度に1文字を読み込み、最後にヌル文字を代入して文字列全体を終了させることを計画しています。それが動作することを願って! – jdek