我已经在服务器和客户端程序中以名称41440
硬编码了端口号SERV_TCP_PORT
。服务器代码使我在编译时没有错误,但是我的客户端调用了
perror("client connect")
错误并输出消息connection refused
。我假设它与端口分配有关,但是这里可能出什么问题了?
客户代码:
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h> /* struct sockaddr_in, htons, htonl */
#include <netdb.h> /* struct hostent, gethostbyname() */
#include <string.h>
#define SERV_TCP_PORT 41440
#define MAX_BLOCK_SIZE 256 /* default server listening port */
int main(int argc, char *argv[])
{
int sd, n, nr, nw, i=0;
char buf[MAX_BLOCK_SIZE], buf2[MAX_BLOCK_SIZE], host[60];
unsigned short port;
struct sockaddr_in ser_addr; struct hostent *hp;
/* get server host name and port number */
port = SERV_TCP_PORT;
if (argc==1) { /* assume server running on the local host and on default port */
strcpy(host, "localhost");
}
else if (argc == 2) { /* use the given host name */
strcpy(host, argv[1]);
}
/* get host address, & build a server socket address */
bzero((char *) &ser_addr, sizeof(ser_addr));
ser_addr.sin_family = AF_INET;
ser_addr.sin_port = htons(port);
if ((hp = gethostbyname(host)) == NULL){
printf("host %s not found\n", host); exit(1);
}
ser_addr.sin_addr.s_addr = * (u_long *) hp->h_addr;
/* create TCP socket & connect socket to server address */
sd = socket(PF_INET, SOCK_STREAM, 0);
if (connect(sd, (struct sockaddr *) &ser_addr, sizeof(ser_addr))<0) {
perror("client connect");
exit(1);
}
服务器代码:
#include <unistd.h>
#include <sys/stat.h>
#include <stdlib.h> /* strlen(), strcmp() etc */
#include <stdio.h> /* printf() */
#include <string.h> /* strlen(), strcmp() etc */
#include <errno.h> /* extern int errno, EINTR, perror() */
#include <signal.h> /* SIGCHLD, sigaction() */
#include <syslog.h>
#include <sys/types.h> /* pid_t, u_long, u_short */
#include <sys/socket.h> /* struct sockaddr, socket(), etc */
#include <sys/wait.h> /* waitpid(), WNOHAND */
#include <netinet/in.h> /* struct sockaddr_in, htons(), htonl(), */
/* and INADDR_ANY */
#define SERV_TCP_PORT 41440 /* default server listening port */
#define MAX_BLOCK_SIZE 256
void claim_children()
{
pid_t pid=1;
while (pid>0) { /* claim as many zombies as we can */
pid = waitpid(0, (int *)0, WNOHANG);
}
}
void daemon_init(void)
{
pid_t pid;
struct sigaction act;
if ( (pid = fork()) < 0) {
perror("fork"); exit(1);
} else if (pid > 0) {
printf("Hay, you'd better remember my PID: %d\n", pid);
exit(0); /* parent goes bye-bye */
}
/* child continues */
setsid(); /* become session leader */
chdir("/"); /* change working directory */
umask(0); /* clear file mode creation mask */
/* catch SIGCHLD to remove zombies from system */
act.sa_handler = claim_children; /* use reliable signal */
sigemptyset(&act.sa_mask); /* not to block other signals */
act.sa_flags = SA_NOCLDSTOP; /* not catch stopped children */
sigaction(SIGCHLD,(struct sigaction *)&act,(struct sigaction *)0);
/* note: a less than perfect method is to use
signal(SIGCHLD, claim_children);
*/
}
void result(char *s)
{
char cwd[MAX_BLOCK_SIZE];
if(strcmp(s, "pwd") == 0){
printf("Checking if pwd is recognized");
if(getcwd, sizeof(cwd) != NULL){
strcpy(s, cwd);
}
}
}
void serve_a_client(int sd)
{
int nr, nw, i = 0;
char buf[MAX_BLOCK_SIZE];
char directory[MAX_BLOCK_SIZE];
while (1){
/* read data from client */
if ((nr = read(sd, buf, sizeof(buf))) <= 0){
printf("Connection broken down.");
exit(0); /* connection broken down */
}
/* process data */
buf[nr] = '\0';
result(buf);
/* send results to client */
nw = write(sd, buf, nr);
}
}
int main(int argc, char *argv[])
{
int sd, nsd, n;
pid_t pid;
unsigned short port; // server listening port
socklen_t cli_addrlen;
struct sockaddr_in ser_addr, cli_addr;
/* get the port number */
port = SERV_TCP_PORT;
if (argc == 2) {
if(chdir(argv[1]) == 0){
printf("Server directory changed to %s \n", argv[1]);
}
else{
printf("%s is an invalid directory.\n", argv[1]);
exit(1);
}
}
else {
printf("Usage: %s [ server listening port ]\n", argv[0]);
exit(1);
}
/* turn the program into a daemon */
daemon_init();
/* set up listening socket sd */
if ((sd = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
perror("server:socket"); exit(1);
}
/* build server Internet socket address */
bzero((char *)&ser_addr, sizeof(ser_addr));
ser_addr.sin_family = AF_INET;
ser_addr.sin_port = htons(port);
ser_addr.sin_addr.s_addr = htonl(INADDR_ANY);
/* note: accept client request sent to any one of the
network interface(s) on this host.
*/
/* bind server address to socket sd */
if (bind(sd, (struct sockaddr *) &ser_addr, sizeof(ser_addr))<0){
perror("server bind"); exit(1);
}
/* become a listening socket */
listen(sd, 5);
while (1) {
/* wait to accept a client request for connection */
cli_addrlen = sizeof(cli_addr);
nsd = accept(sd, (struct sockaddr *) &cli_addr, (socklen_t *)&cli_addrlen);
if (nsd < 0) {
if (errno == EINTR) /* if interrupted by SIGCHLD */
continue;
perror("server:accept"); exit(1);
}
/* create a child process to handle this client */
if ((pid=fork()) <0) {
perror("fork"); exit(1);
} else if (pid > 0) {
close(nsd);
continue; /* parent to wait for next client */
}
/* now in child, serve the current client */
close(sd);
serve_a_client(nsd);
}
}