我需要做简单的客户端程序,当我添加端口号时,客户端将搜索该端口的所有服务。现在的问题是 if 语句中存在段错误。 如何退回所有服务?我想,在我的程序中,它只会返回一个。
我的代码:
int main (int argc, char *argv[])
{
int sockfd, n,pol, s;
int numer;
char recvline[MAXLINE +1];
char p;
struct sockaddr_in servaddr;
struct servent *sp;
if (argc != 3)
err_sys("Aby uruchomić podaj: klient <Adres IP> <port>");
s = atoi(argv[2]);
if((sp = getservbyport(s,NULL)) == NULL)
{
printf("port (s): %d \n", s);
printf("port (sp): %d \n", sp->s_port); //segmentation fault
err_sys("problem with port");
}
if((sockfd = socket(AF_INET, SOCK_STREAM, 0))<0)
err_sys("Blad utworzenia polaczenia");
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = sp->s_port;
if(inet_pton(AF_INET, argv[1], &servaddr.sin_addr)<=0)
err_sys_kom("Blad konwersji do adresu IP dla %s", argv[1]);
printf("%s", sp->s_name);
pol = connect(sockfd, (SA*) &servaddr, sizeof(servaddr));
if (pol < 0)
{
err_sys_kom("Blad polaczenie z serwerem");
close(sockfd);
exit(-1);
}
else
str_cli(stdin, sockfd , 1);
exit(0);
}
最佳答案
编辑(响应新问题 - 请参阅下面的评论):
您可能需要获取 protocols 的列表并与那些循环中的人一起工作。循环的内容大致应该是:
- 调用
getprotoent
- 如果结果为NULL,则退出循环。
- 否则,从返回的结构中挖掘出协议(protocol)名称。
- 使用该名称作为
getservbyport
的第二个参数 - 对结果做你想做的事情
编辑(响应新问题):
if((sp = getservbyport(s,NULL)) == NULL)
因此,您的逻辑是仅当 sp
为 NULL
时才读取 sp
。显然它会出现段错误。
应该是:
if((sp = getservbyport(s,NULL)) != NULL)
但是你会指出另一个新问题:
为什么sp
为NULL?
这可能是因为(根据我答案的早期版本),您对一些不是整数执行了atoi
。可能是因为任何其他原因。我们不能说,因为我们不知道您提供了什么输入。
以下部分答案是为了回应OP在同一问题中提出的一个老问题,并从那时起选择对其进行编辑:
首先:由于您使用的是 getservbyport
,因此您确实应该阅读 services ,如果您还没有的话。
现在来看看错误:
getservbyport
属于类型:
struct servent *getservbyport(int port, const char *proto);
您传递的 argv[2]
类型为 char *
,而不是 port
的 int
.
我相信用户将其作为参数输入到您的程序中?
如果您知道 char *
指向一组看起来像整数的字符,例如“1024”,那么您可以将其转换为整数 atoi
.
在调用 getservbyport
时,在出现错误的行执行此操作,同时确保已包含 stdlib.h
:
getservbyport(atoi(argv[2]),NULL)
如果 argv[2]
不能表示为整数,您将得到未定义的行为,所以也许您需要先检查一下。
关于客户端 - 使用 servbyport() 函数搜索所有服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10911481/