我正在编写连接服务器的客户端。我在TCP套接字的第124行memcpy()上遇到了分段错误。 使用UDP连接我想获取网络上服务器的IP地址,然后,获取IP,我想通过TCP连接与它连接。 TCP连接的代码本身有效,因为在新文件中我可以编译。我不明白问题出在哪里。
#include <stdio.h>
#include <sys/types.h>
#include <ifaddrs.h>
#include <netinet/in.h>
#include <string.h>
#include <arpa/inet.h>
#include <string.h>
#include <memory.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <netdb.h>
#include "main.h"
int developer=1;
struct myHelloMsg {
char myIp[25];
char myID[25];
};
int FindMyIp(char myIpAddr[], char myMask[], char myBroad[]);
int RecvBroadTime(int sockfd, struct sockaddr_in server_addr);
void CheckID(char myUserID[]);
int main() {
char myIpAddr[25], myMask[25], myBroad[25], myUserID[25]="";
char otherUserIp[25], otherUserID[25];
struct myHelloMsg myMsg, rxMsg;
CheckID(myUserID);
int checkConnection;
disconnected: ;
checkConnection=0;
if (developer==1) printf("\nSearching for a network..\n");
while (checkConnection == 0) {
checkConnection = FindMyIp(myIpAddr, myMask, myBroad);
if (checkConnection==0) {
if (developer==1) printf("--Disconnected..\n");
sleep(5);
}
}
if (developer==1) printf("\n--Connected..\nIP Address\t: %s\n", myIpAddr);
if (developer==1) printf("Subnet Mask\t: %s\n", myMask);
if (developer==1) printf("Broadcast IP\t: %s\n", myBroad);
int i=0;
for (i=0;i<25;i++) {
myMsg.myIp[i]=myIpAddr[i];
myMsg.myID[i]=myUserID[i];
}
struct hostent *hptr = gethostbyname(myBroad);
if (hptr == NULL) {
if (developer==1) printf("Error while transmitting broadcast message..\n");
return 0;
}
// create socket for initial UDP communication
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in server_addr;
bzero(&server_addr, sizeof(struct in_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(5051);
server_addr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
memcpy(&server_addr.sin_addr, hptr->h_addr_list[0], sizeof(struct in_addr));
int opt = 1;
setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &opt, sizeof(int));
int error=0;
if (developer==1) printf("--Contacting other users in the network..\n");
sendto(sockfd, &myMsg, sizeof(myMsg), 0, (struct sockaddr *) &server_addr, sizeof(struct sockaddr_in));
int foundSomeone=0;
//try to connect with others for 5 times - because of UDP unreliable connection
int countTries=0, received=0, lastTry=0;
while (countTries<5) {
foundSomeone = RecvBroadTime(sockfd, server_addr);
if (foundSomeone == 1) {
if (developer==1) printf("An answer has been received..\n");
socklen_t ssize = sizeof(struct sockaddr_in);
recvfrom(sockfd, &rxMsg, sizeof(rxMsg), 0, (struct sockaddr *) &server_addr, &ssize);
received=1;
countTries=5;
}
else if (foundSomeone == 0) {
if (developer==1) printf("Timeout(%d try)..\n", countTries+1);
sendto(sockfd, &myMsg, sizeof(myMsg), 0, (struct sockaddr *) &server_addr, sizeof(struct sockaddr_in));
if (countTries==4) {
lastTry=1;
}
}
else {
if (developer==1) printf("--Error..\n");
}
countTries++;
}
if ((lastTry==1)&&(countTries==5)) {
foundSomeone = RecvBroadTime(sockfd, server_addr);
if (foundSomeone == 1) {
if (developer==1) printf("An answer has been received..\n");
socklen_t ssize = sizeof(struct sockaddr_in);
recvfrom(sockfd, &rxMsg, sizeof(rxMsg), 0, (struct sockaddr *) &server_addr, &ssize);
received=1;
}
else if (foundSomeone == 0) {
if (developer==1) printf("--No one is connected to the current network..\n");
}
else {
if (developer==1) printf("There has been an error while trying to contact other users..\n");
}
}
close(sockfd);
// someone else is connected to the network
// i am gonna behave as a client in during the synchronization step
if (received==1) {
if (developer==1) printf("Contact made with user %s (%s).\n", myMsg.myID, myMsg.myIp);
// check if the user belong to friends i am sharing content with
i=0;
for (i=0;i<25;i++) {
otherUserIp[i]=rxMsg.myIp[i];
otherUserID[i]=rxMsg.myID[i];
}
int socktcp = socket(AF_INET, SOCK_STREAM, 0);
struct hostent *hptr_tcp = gethostbyname(otherUserIp);
struct sockaddr_in server_addr_tcp;
bzero(&server_addr_tcp, sizeof(struct sockaddr_in));
server_addr_tcp.sin_family = AF_INET;
server_addr_tcp.sin_port = htons(5054);
printf("a\n");
memcpy(&server_addr_tcp.sin_addr, hptr_tcp->h_addr_list[0], sizeof(struct in_addr));
printf("a\n");
if (connect(socktcp, (struct sockaddr *) &server_addr_tcp, sizeof(struct sockaddr_in))<0) {
printf("-Error..\n");
} else {
printf("Connection with %s established.. Ready for synchronization step..\n", otherUserID);
}
}
return 0;
}
int RecvBroadTime(int sockfd, struct sockaddr_in server_addr) {
fd_set socks;
struct timeval t;
t.tv_sec = 1;
t.tv_usec = 0;
FD_ZERO(&socks);
FD_SET(sockfd, &socks);
return select(sockfd+1, &socks, NULL, NULL, &t);
}
int FindMyIp(char myIpAddr[], char myMask[], char myBroad[]) {
struct ifaddrs * ifAddrStruct=NULL;
struct ifaddrs * ifa=NULL;
void * tmpAddrPtr=NULL;
getifaddrs(&ifAddrStruct);
int i=0, connected=0;
ifa = ifAddrStruct;
while (i!=1) {
if (((ifa ->ifa_addr->sa_family==AF_INET)&&(ifa->ifa_name[0]=='e')&&(ifa->ifa_name[1]=='n')&&(ifa->ifa_name[2]=='1'))||((ifa ->ifa_addr->sa_family==AF_INET)&&(ifa->ifa_name[0]=='e')&&(ifa->ifa_name[1]=='t')&&(ifa->ifa_name[2]=='h')&&(ifa->ifa_name[3]=='0'))) {
i=1;
connected=1;
} else {
if (ifa->ifa_next == NULL) return connected;
ifa = ifa->ifa_next;
}
}
tmpAddrPtr=&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
inet_ntop(AF_INET, tmpAddrPtr, myIpAddr, INET_ADDRSTRLEN);
tmpAddrPtr=&((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr;
inet_ntop(AF_INET, tmpAddrPtr, myMask, INET_ADDRSTRLEN);
tmpAddrPtr=&((struct sockaddr_in *)ifa->ifa_broadaddr)->sin_addr;
inet_ntop(AF_INET, tmpAddrPtr, myBroad, INET_ADDRSTRLEN);
return connected;
}
void CheckID(char myUserID[]) {
FILE *fp;
if((fp=fopen("userData.txt", "r+"))==NULL) {
printf("Error while opening the file..\n");
}
else {
fscanf(fp, "%25s", myUserID);
if (strlen(myUserID)==0) {
printf("First time you open this app..\nInsert your User ID: ");
scanf("%s", myUserID);
fprintf(fp, "%-25s", myUserID);
}
else {
printf("Welcome back %s..\n", myUserID);
}
fclose(fp);
}
}
答案 0 :(得分:1)
我要说使用gethostbyname()
无法解析广播地址。
另外:gethostbyname()
已过时,请改用getnameinfo()
。