//serv.c
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <getopt.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <netinet/in.h>
#include <netdb.h>
#include <poll.h>
#include <signal.h>
#include <string.h>
#include <sys/wait.h>
int main(int argc, char *argv[])
{
FILE *log;
int port_no;
struct sockaddr_in server_addr;
struct hostent* server; int port_flag=0;
int c;
while(1)
{
static struct option long_options[]=
{
{"port",required_argument,0,'p'},
{"log",required_argument,0,'l'},
};
c= getopt_long(argc,argv,"p:l",long_options,NULL);
if(c==-1)
break;
switch(c)
{
case 'l':
if(optarg)
{
if(optarg[0]!='-')
{
log= fopen(optarg,"w");
}
else
{
fprintf(stderr,"log requires argument\n");
}
}
break;
case 'p':
if(optarg)
{
if(optarg[0]!='-')
{
port_no= atoi(optarg);
port_flag=1;
}
else{
printf("Usage --port=PORT_NUMBER\n");
}
}
else
{
printf("Usage --port=PORT_NUMBER\n");
}
break;
case '?':
write(STDOUT_FILENO,"\r",1);
exit(1);
break;
default:
break;
}
}
int opt = 0, port_num, client_len;
struct sockaddr_in server_addr, client_addr;
socket_fd = socket(AF_INET, SOCK_STREAM, 0);
if(socket_fd < 0) { perror("Error opening socket"); exit(1); }
memset((char*) &server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port_num);
server_addr.sin_addr.s_addr = INADDR_ANY;
if(bind(socket_fd, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0)
{
perror("Error binding socket");
exit(1);
}
listen(socket_fd,5);
client_len=sizeof(client_addr);
newsocket_fd=accept(socket_fd,(struct sockaddr *)&client_addr,&client_len);
printf("accepting");
if(newsocket_fd<0)
{
fprintf(stderr,"error on accept");
}
char buffer[256];
memset(buffer,0,256);
int n=read(newsocket_fd,buffer,255);
if(n<0)
{
fprintf(stderr,"Error reading from socket");
}
printf("Here is the message: %s\n",buffer);
n=write(newsocket_fd,"I got your message",18);
}
client.c
int main(int argc, char *argv[])
{
FILE *log;
int port_no;
struct sockaddr_in server_addr;
struct hostent* server; int port_flag=0;
int c;
while(1)
{
static struct option long_options[]=
{
{"port",required_argument,0,'p'},
{"log",required_argument,0,'l'},
};
c= getopt_long(argc,argv,"p:l",long_options,NULL);
if(c==-1)
break;
switch(c)
{
case 'l':
if(optarg)
{
if(optarg[0]!='-')
{
log= fopen(optarg,"w");
}
else
{
fprintf(stderr,"log requires argument\n");
}
}
break;
case 'p':
if(optarg)
{
if(optarg[0]!='-')
{
port_no= atoi(optarg);
port_flag=1;
}
else{
printf("Usage --port=PORT_NUMBER\n");
}
}
else
{
printf("Usage --port=PORT_NUMBER\n");
}
break;
case '?':
write(STDOUT_FILENO,"\r",1);
exit(1);
break;
default:
break;
}
}
char buffer[256];
socket_fd = socket(AF_INET, SOCK_STREAM, 0);
if(socket_fd < 0) { perror("Error opening socket"); exit(0); }
server = gethostbyname("localhost");
if(server == NULL) { fprintf(stderr, "Cannot find host"); exit(0); }
//Initialize the server address to zero and then correctly assign it
memset((char*) &server_addr,0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
memcpy((char *) &server_addr.sin_addr.s_addr,
(char*) server->h_addr,
server->h_length);
server_addr.sin_port = htons(port_no);
if(connect(socket_fd,(struct sockaddr *) &server_addr, sizeof(server_addr)) < 0) { perror("Error connecting"); exit(0); }
printf("Please enter the message");
memset(buffer,0,256);
fgets(buffer,255,stdin);
int n=write(socket_fd,buffer,strlen(buffer));
if(n<0)
{
fprintf(stderr,"error writing to socket");
}
memset(buffer,0,256);
n=read(socket_fd,buffer,255);
if(n<0)
{
printf("Error reading");
}
printf("%s\n",buffer);}
}
我不知道为什么,但服务器似乎不接受套接字 来自客户的连接。我尝试过超过1024的端口号。只是 不起作用。端口号是用户输入的。是否只有port_no可用于它?
答案 0 :(得分:1)
您发布的“完整代码”未完整,因为它无法编译(提示:client.c不包含单个头文件)。通过简单的修复,一个重要的线索来自编译并启用警告:
$ gcc -g serv.c -o serv -Wall -Wextra
serv.c: In function 'main':
serv.c:94:71: warning: pointer targets in passing argument 3 of 'accept' differ in signedness [-Wpointer-sign]
int newsocket_fd=accept(socket_fd,(struct sockaddr *)&client_addr,&client_len);
^
In file included from serv.c:7:0:
/usr/include/x86_64-linux-gnu/sys/socket.h:243:12: note: expected 'socklen_t * __restrict__' but argument is of type 'int *'
extern int accept (int __fd, __SOCKADDR_ARG __addr,
^
serv.c:79:5: warning: unused variable 'opt' [-Wunused-variable]
int opt = 0, port_num, client_len;
^
serv.c:23:36: warning: variable 'port_flag' set but not used [-Wunused-but-set-variable]
struct hostent* server; int port_flag=0;
^
serv.c:23:21: warning: unused variable 'server' [-Wunused-variable]
struct hostent* server; int port_flag=0;
^
serv.c:21:9: warning: variable 'port_no' set but not used [-Wunused-but-set-variable]
int port_no;
^
serv.c:20:11: warning: variable 'log' set but not used [-Wunused-but-set-variable]
FILE *log;
^
serv.c:111:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
serv.c:85:28: warning: 'port_num' may be used uninitialized in this function [-Wmaybe-uninitialized]
server_addr.sin_port = htons(port_num);
看看最后一次警告 - “port_num”未初始化?再看一下:“port_no”已初始化但未使用?因此,参数处理是徒劳的,你正在监听任意端口 - 检查@Pras的“netstat -l -p”的建议也会显示出来。
作为一种调试策略,值得用迂腐警告进行编译(并尝试使用像clang这样的更多诊断编译器)来寻找线索。作为一种常见的开发策略,通过始终启用警告并在运行代码之前修复它们来减少调试时间。
答案 1 :(得分:0)
因为您在这里询问服务器是我注意到的。
两者&#34; port_no&#34;和&#34; port_num&#34;声明,用户输入它分配给&#34; port_no&#34;但你正在使用&#34; port_num&#34;当调用htons()时。
您的切换案例后重新声明'server_addr',并且还缺少newsocket_fd
$gcc -o server server.c
server.c: In function ‘main’:
server.c:80:24: error: redeclaration of ‘server_addr’ with no linkage
struct sockaddr_in server_addr, client_addr;
^~~~~~~~~~~
server.c:22:24: note: previous declaration of ‘server_addr’ was here
struct sockaddr_in server_addr;
^~~~~~~~~~~
server.c:81:5: error: ‘socket_fd’ undeclared (first use in this function)
socket_fd = socket(AF_INET, SOCK_STREAM, 0);
^~~~~~~~~
server.c:81:5: note: each undeclared identifier is reported only once for each function it appears in
server.c:94:5: error: ‘newsocket_fd’ undeclared (first use in this function)
newsocket_fd=accept(socket_fd,(struct sockaddr *)&client_addr,&client_len);
无论哪种方式,我移除了开关盒并手动分配了端口号以使其运行,您需要检查输入并清除一些错误,但这是一个代码的工作示例,其中包含有关更改的注释。 / p>
我使用netcat作为客户端来测试连接。
$ netcat 127.0.0.1 5555
test message
I got your message
输出代码与您提供的内容没有变化,这是它将显示的内容。使用&#34; \ n&#34;换行。
$gcc -o server server.c
example@pc:~$./server
acceptingHere is the message: test message
以下是修改后的代码:
//serv.c
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <getopt.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <netinet/in.h>
#include <netdb.h>
#include <poll.h>
#include <signal.h>
#include <string.h>
#include <sys/wait.h>
int main(int argc, char *argv[])
{
FILE *log;
// Added socket_fd and newsocket_fd
int socket_fd, newsocket_fd;
// use uint16_t for port number
uint16_t port_no;
//Removed struct sockaddr_in server_addr;
struct hostent* server; int port_flag=0;
int c;
port_no = 5555;
/* removed switch to show server does function
while(1)
{
static struct option long_options[]=
{
{"port",required_argument,0,'p'},
{"log",required_argument,0,'l'},
};
c= getopt_long(argc,argv,"p:l",long_options,NULL);
if(c==-1)
break;
switch(c)
{
case 'l':
if(optarg)
{
if(optarg[0]!='-')
{
log= fopen(optarg,"w");
}
else
{
fprintf(stderr,"log requires argument\n");
}
}
break;
case 'p':
if(optarg)
{
if(optarg[0]!='-')
{
port_no= atoi(optarg);
port_flag=1;
}
else{
printf("Usage --port=PORT_NUMBER\n");
}
}
else
{
printf("Usage --port=PORT_NUMBER\n");
}
break;
case '?':
write(STDOUT_FILENO,"\r",1);
exit(1);
break;
default:
break;
}
}
*/
// Removed port_num
int opt = 0, client_len;
struct sockaddr_in server_addr, client_addr;
socket_fd = socket(AF_INET, SOCK_STREAM, 0);
if(socket_fd < 0) { perror("Error opening socket"); exit(1); }
memset((char*) &server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
// using port_no in htons
server_addr.sin_port = htons(port_no);
server_addr.sin_addr.s_addr = INADDR_ANY;
if(bind(socket_fd, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0)
{
perror("Error binding socket");
exit(1);
}
listen(socket_fd,5);
client_len=sizeof(client_addr);
newsocket_fd=accept(socket_fd,(struct sockaddr *)&client_addr,&client_len);
printf("accepting");
if(newsocket_fd<0)
{
fprintf(stderr,"error on accept");
}
char buffer[256];
memset(buffer,0,256);
int n=read(newsocket_fd,buffer,255);
if(n<0)
{
fprintf(stderr,"Error reading from socket");
}
printf("Here is the message: %s\n",buffer);
n=write(newsocket_fd,"I got your message",18);
}