[英]C Client Server Connection Refused
I have a laptop running windows 10 and intalled ubuntu in Oracle VM Virtualbox Machine. 我有一台笔记本电脑在Oracle VM Virtualbox Machine中运行Windows 10和安装的ubuntu。 I have the following server and and client source code.
我有以下服务器和客户端源代码。 I run the server first then the client.
我先运行服务器,然后运行客户端。 But it gave me a connection refused.
但这给了我一个拒绝的联系。 Tried netstat -ntlp then found out that there is actually no port listening to the specific port I typed.
经过尝试的netstat -ntlp然后发现实际上没有端口在监听我键入的特定端口。
server.c server.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/utsname.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<netdb.h>
#include<unistd.h>
int _GetHostName(char *buffer, int lenght);
const char MESSAGE[]="Hello, World!\n";
const int BACK_LOG=5;
int main(int argc, char *argv[]){
int serverSocket=0, on=0, port=0, status=0, childPid=0;
struct hostent *hostPtr=NULL;
char hostname[80]="";
struct sockaddr_in serverName={0};
if(2!= argc){
fprintf(stderr, "Usage : %s <port>\n", argv[0]);
exit(1);
}
port=atoi(argv[1]);
serverSocket=socket(PF_INET,SOCK_STREAM, IPPROTO_TCP);
if(-1==serverSocket){
perror("socket()");
exit(1);
}
on=1;
status=setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, (const char *)&on, sizeof(on));
if(-1==status){
perror("setsockopt(...,SO_REUSEADDRE,...)");
}
{
struct linger linger={0};
linger.l_onoff=1;
linger.l_linger=30;
status=setsockopt(serverSocket, SOL_SOCKET, SO_LINGER, (const char*)&linger, sizeof(linger));
if(-1==status){
perror("setsockopt(...,SO_LINGER,...)");
}
}
status=_GetHostName(hostname, sizeof(hostname));
if(-1==status){
perror("_GetHostName()");
exit(1);
}
hostPtr=gethostbyname(hostname);
if(NULL==hostPtr){
perror("gethostbyname()");
exit(1);
}
(void)memset(&serverName,0,sizeof(serverName));
(void)memcpy(&serverName.sin_addr, hostPtr->h_addr,hostPtr->h_length);
serverName.sin_family=AF_INET;
serverName.sin_port=htons(port);
status=bind(serverSocket, (struct sockaddr*)&serverName,sizeof(serverName));
if(-1==status){
perror("bind");
exit(1);
}
status=listen(serverSocket, BACK_LOG);
if(-1==status){
perror("listen()");
exit(1);
}
for(;;){
struct sockaddr_in clientName={0};
int slaveSocket, clientLength=sizeof(clientName);
(void)memset(&clientName,0,sizeof(clientName));
slaveSocket=accept(serverSocket,(struct sockaddr*)&clientName, & clientLength);
if(-1==slaveSocket){
perror("accept()");
exit(1);
}
childPid=fork();
switch(childPid){
case -1:perror("fork()");
exit(1);
case 0: close(serverSocket);
if(-1==getpeername(slaveSocket, (struct sockaddr*)&clientName, &clientLength)){
perror("getpeername()");
}else{
printf("Connection request from %s \n", inet_ntoa(clientName.sin_addr));
}
/*
Server Application specific code here
response to client
*/
write(slaveSocket,MESSAGE,strlen(MESSAGE));
close(slaveSocket);
exit(0);
default:close(slaveSocket);
}
}
return 0;
}
int _GetHostName(char *buffer,int length){
struct utsname sysname={0};
int status=0;
status=uname(&sysname);
if(-1!=status){
strncpy(buffer,sysname.nodename,length);
}
return(status);
}
client.c client.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <string.h>
int main(int argc, char *argv[]){
int clientSocket, remotePort, status=0;
struct hostent *hostPtr=NULL;
struct sockaddr_in serverName={0};
char buffer[256]="";
char *remoteHost=NULL;
if(3!=argc){
fprintf(stderr, "Usage: %s <serverHost> <serverPort> \n",argv[0]);
exit(1);
}
remoteHost=argv[1];
remotePort=atoi(argv[2]);
clientSocket=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
if(-1==clientSocket){
perror("socket()");
exit(1);
}
hostPtr=gethostbyname(remoteHost);
if(NULL==hostPtr){
hostPtr=gethostbyaddr(remoteHost,strlen(remoteHost), AF_INET);
if(NULL==hostPtr){
perror("Error resolving server address ");
exit(1);
}
}
serverName.sin_family=AF_INET;
serverName.sin_port=htons(remotePort);
(void)memcpy(&serverName.sin_addr,hostPtr->h_addr,hostPtr->h_length);
status=connect(clientSocket,(struct sockaddr*)&serverName,sizeof(serverName));
if(-1==status){
perror("connect()");
exit(1);
}
//CLIENT SPECIFIC HERE
while(0 < (status=read(clientSocket, buffer,sizeof(buffer)-1)))
printf("%d: %s", status, buffer);
if(-1==status)perror("read()");
close(clientSocket);
return 0;
}
As you can see in the server console, the call to gethostbyname is failing. 在服务器控制台中可以看到,对gethostbyname的调用失败。 This function sets h_errno, not errno, so you can't use perror to output the error.
此函数设置h_errno而不是errno,因此您不能使用perror输出错误。 This is why you see it claim "success".
这就是为什么您看到它声称“成功”的原因。
I don't see the point of using gethostbyname here though, most servers default to using INADDR_ANY when the address isn't specified by the user. 我在这里看不到使用gethostbyname的意义,当用户未指定地址时,大多数服务器默认使用INADDR_ANY。
As Joni already pointed out, your program fails at gethostbyname()
in server.c and then exits. 正如Joni所指出的那样,您的程序在server.c中的
gethostbyname()
处失败,然后退出。 Therefore no port gets bound since your program isn't running anymore. 因此,由于您的程序不再运行,因此没有端口绑定。
Just don't use the gethostbyname()
function if it's not really necessary and set sin_addr
directly like in one of the following examples: 只是如果确实没有必要,不要使用
gethostbyname()
函数,而是像以下示例之一一样直接设置sin_addr
:
// let the kernel fill in the address of your interface for you automatically
serverName.sin_addr.s_addr = htonl(INADDR_ANY);
// use a loopback address (127.0.0.1) = localhost
serverName.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
// use whatever address you like
serverName.sin_addr.s_addr = inet_addr("127.1.1.1");
Don't forget to remove the line 别忘了删除行
memcpy(&serverName.sin_addr, hostPtr->h_addr,hostPtr->h_length);
in server.c when you set sin_addr
like in the examples above. 如上例所示,在server.c中设置
sin_addr
时。
Just figured it out. 只是想通了。 There is actually no problem in the code.
代码中实际上没有问题。 The reason why I got an error particularly in the following line is that because just after I installed ubuntu in the virtual box, I changed the device name of the ubuntu without changing the
etc/hosts
. 之所以出现错误,尤其是在下一行中出现错误,是因为在虚拟机中安装了ubuntu之后,我更改了ubuntu的设备名称而未更改
etc/hosts
。
hostPtr=gethostbyname(hostname);
if(NULL==hostPtr){
perror("gethostbyname()");
exit(1);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.