我为你带来了一些新的麻烦。我在C学习套接字和TCP / IPv4。我必须写一个战舰游戏,我对此感到非常兴奋。但我无法解决一些问题。所以这是我的情况。
我有一台服务器和多个客户端。每个客户都可以挑战或受到其他客户的质疑。服务器等待客户端写入univoque ID。写入ID后,服务器将扫描struct sockaddr
数组,并找到与先前读取的ID相关的数组。然后它调用inet_ntoa()
使IP成为字符串并将其写入客户端。一旦客户端读取了IP,它就会与另一个客户端建立新的直接连接并开始玩战舰。
好的,这就是场景。我正在努力解决的问题首先是如何从inet_ntoa()
中获取univoque IP地址,因为我在同一主机上的终端中执行每个客户端实例。其次,每个客户端都应接受来自其他客户端的传入连接所以我为每个客户端提供了2个套接字:一个用于客户端 - 服务器通信,另一个用于侦听可能的挂起连接(此套接字将放在readfd
的{{1}}中。问题是,一旦我开始新客户端 - 如果另一个客户端已经连接并等待挑战或被质疑 - 我必须指定客户端将连接到的服务器的IP。因此,无论我使用select()
还是主机IP地址,客户端的新功能都会尝试连接到已连接的客户端(因为它的套接字处于127.0.0.1
状态)而不是服务器。我认为它与端口有关,但我不知道如何实现我想做的事情(已经尝试更改端口等)。
以下是代码的一些行。我省略了明显的事情(请不要因为最后一句话而杀了我)。
客户代码:
listen
服务器代码:
struct sockaddr_in servaddr, claddr,cl2addr;
servaddr.sin_family=AF_INET; //used for the client-server connection
servaddr.sin_port=htons(8888); //port 8888 for the client-server communication
servaddr.sin_addr.s_addr=inet_addr(argv[1]); //argv[1]=IP of the server
cl2addr.sin_family=AF_INET; //this will be used for the client-client new connection
cl2addr.sin_port=htons(9990);//listen on the port 9990
cl2addr.sin_addr.s_addr=INADDR_ANY; //for any client to connect
servsock=socket(PF_INET,SOCK_STREAM,0);
listenfd=socket(PF_INET,SOCK_STREAM,0);
if (bind(listenfd,(struct sockaddr*)&cl2addr,sizeof(cl2addr))<0)
{
perror("Binding: "); //This printf "Address already in use"
exit(-1);
}
if (listen(listenfd,1)<0)
{
perror("Listening: ");
exit(-1);
}
if (servsock<0)
{
perror("Creating socket: ");
exit(-1);
}
if (connect(servsock,(struct sockaddr*)&servaddr,sizeof(servaddr))<0) //estabilish a connection with the main server
{
perror("Connect: ");
exit(-1);
}
//some code with the select etc. inside //
if ((mastfd=accept(listenfd,(struct sockaddr *) &claddr,&cllen))<0)
{
perror("Accept: ");
exit(-1);
}
聚苯乙烯。
通常,从服务器到客户端写入的IP都为struct sockaddr_in servaddr, claddr[10]; //che claddr array holds every IP in the sin_addr.s_addr field
int conn=0;
servaddr.sin_family=AF_INET;
servaddr.sin_port=htons(8888);
servaddr.sin_addr.s_addr=INADDR_ANY;
listenfd=socket(PF_INET,SOCK_STREAM,0);
if (listenfd<0)
{
perror("Socket: ");
exit(-1);
}
if(setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(opt))<0)
{
perror("setsockopt");
exit(-1);
}
if (bind(listenfd,(struct sockaddr *)&servaddr, sizeof(servaddr))<0)
{
perror("Bind: ");
exit(-1);
}
if (listen(listenfd,10)<0)
{
perror("Listen: ");
exit(-1);
}
//here goes a while loop//
{
FD_SET(listenfd,&readfd);
select(maxfd,&readfd,NULL,NULL,&elaps);
accept(listenfd,(struct sockaddr *)&claddr[conn],&len);
conn++;
//here the server waits for a client to write the ID to challenge, find the relative position in the claddr array and then writes the ip to the client//
m=strlen(ipbuff); //calculate the lenght of the IP
nwrite=write(att,&m,sizeof(m)); //write the lenght to the client
if (nwrite<0)
{
perror("Writing LEN: ");
_exit(-1);
}
nwrite=write(att,ipbuff,m); //write the IP to the client
if (nwrite<0)
{
perror("Writing IP: ");
_exit(-1);
}
}
,类似于len=2
或00
。这是因为它返回本地机器的ip地址,对吧?
谢谢你们,顺便说一下。如果代码是缩进或其他东西,请随意扔我的***。