我必须创建一个TCP / IP服务器/客户端套接字程序,其中服务器和客户端必须位于相同的.c文件中。下面是我的代码,如果没有输入命令行参数,则创建服务器并等待另一个进程启动连接。如果输入了一个命令行参数(IP地址),则该进程将接受客户端角色并连接到在特定IP地址执行的其他进程。我只是使用localhost。
当我使用ip地址(./game localhost)运行程序时,我得到了
~/Desktop/a5 20 $ ./game localhost
ERROR connecting: Connection refused
当我运行没有ip地址的程序(./game)时,我得到一个段错误
~/Desktop/a5 19 $ ./game
Segmentation fault (core dumped)
对于我做错的任何帮助都将不胜感激!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#define h_addr h_addr_list[0]
void error(char *msg) {
perror(msg);
exit(1);
}
int main(int argc, char *argv[]) {
int sockfd, newsockfd, portno, clilen, sockfd2, portno2, n, n2;
char buffer[256];
char buffer2[256];
struct sockaddr_in serv_addr, cli_addr, serv_addr2;
struct hostent *server;
portno = 4547;
if (argc == 1) {
sockfd2 = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd2 < 0) {
error("ERROR opening socket");
}
server = gethostbyname(argv[1]);
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
bzero((char *) &serv_addr2, sizeof(serv_addr2));
serv_addr2.sin_family = AF_INET;
bcopy((char *)server->h_addr,(char *)&serv_addr2.sin_addr.s_addr,server->h_length);
serv_addr2.sin_port = htons(portno);
if (connect(sockfd2,(struct sockaddr *)&serv_addr2,sizeof(serv_addr2)) < 0) {
error("ERROR connecting");
}
printf("Please enter the message: ");
bzero(buffer2,256);
fgets(buffer2,255,stdin);
n2 = write(sockfd2,buffer2,strlen(buffer2));
if (n2 < 0) {
error("ERROR writing to socket");
}
printf("%s\n",buffer2);
}
else if (argc == 0) {
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
error("ERROR opening socket");
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
error("ERROR on binding");
}
listen(sockfd,5);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd,(struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0) {
error("ERROR on accept");
}
bzero(buffer,256);
n = read(newsockfd,buffer,255);
if (n < 0) {
error("ERROR reading from socket");
}
printf("Here is the message: %s\n",buffer);
n = write(newsockfd,"I got your message", 18);
if (n < 0) {
error("ERROR writing to socket");
}
}
return 0;
}
答案 0 :(得分:2)
通常argv[0]
是指向执行可执行文件的命令的指针。这意味着argc
始终至少为1 。
增加对argc
的检查,如
if (argc == 1)
一,所以上面的if
子句改为
if (argc == 2)
这是您的细分错误的原因,因为传递给argv[1]
的{{1}}并未指向参数gethostbyname
但是包含argc == 1
作为标准要求NULL
。
请注意,这适用于常见系统。 未在C标准中定义,但在POSIX标准中,AFAIK。