读书人

一个有关C的网络通讯有关问题

发布时间: 2012-04-02 19:58:59 作者: rapoo

一个有关C的网络通讯问题
/*server.c*/

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <errno.h>
#include <malloc.h>

#define MAXLINE 100
int port = 8000;

int main()
{
struct sockaddr_in pin;
struct sockaddr_in sin;
int listen_fd;
int conn_fd;
int sock_fd;
int address = sizeof(pin);
int nready;
int client[FD_SETSIZE];
int maxi;
int maxfd;
int i;
int j;
int n;
int k = 0;
char buf[MAXLINE];
char str[MAXLINE];
fd_set rset;
fd_set allset;

bzero(&sin, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
sin.sin_addr.s_addr = INADDR_ANY;

listen_fd = socket(AF_INET, SOCK_STREAM, 0);

{
int opt = 1;
setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
}

bind(listen_fd, (struct sockaddr *)&sin, sizeof(sin));
listen(listen_fd, 15);
printf( "Accepting connection....\n ");

maxfd = listen_fd;
maxi = -1;
for (i = 0; i < FD_SETSIZE; i++)
{
client[i] = -1;
}

FD_ZERO(&allset);
FD_SET(listen_fd, &allset);

for(;;)
{
rset = allset;
printf( "test -1\n ");
nready = select(maxfd + 1, &rset, NULL, NULL, NULL);
printf( "test -2\n ");
if (FD_ISSET(listen_fd, &rset))
{
conn_fd = accept(listen_fd, (struct sockaddr *)&pin, &address);
for (i = 0; i < FD_SETSIZE; i++)
{
if(client[i] < 0)
{
client[i] = conn_fd;
break;
}
}
if(i == FD_SETSIZE)
{
printf( "too many clients\n ");
exit(1);
}

printf( "New client %s at port %d\n ", inet_ntop(AF_INET, &pin.sin_addr, str, sizeof(str)), ntohs(pin.sin_port));

FD_SET(conn_fd, &allset);
printf( "conn_fd=%d\n ", conn_fd);
if (conn_fd > maxfd)
maxfd = conn_fd;
if (i > maxi)
maxi = i;
if (--nready <= 0)
continue;
} //if
/*start to write*/
for (i = 0; i <= maxi; i++)
{
if((sock_fd = client[i]) < 0)
continue;
if(FD_ISSET(sock_fd, &rset))


{
***inet_ntop(AF_INET, &pin.sin_addr, str, strlen(str));
***printf( "---IP:%s\n ", str);
n = read(sock_fd, buf, MAXLINE);
printf( "test 2\n ");
printf( "sock_fd=%d, buf=%s\n ", sock_fd, buf);
if(n == 0)
{
printf( "%s has been closed.\n ", inet_ntop(AF_INET, &pin.sin_addr, str, sizeof(str)));
fflush(stdout);
close(sock_fd);
FD_CLR(sock_fd, &allset);
client[i] = -1;
}
else
{
printf( "received form client[%d]:%s ", i, buf);
for(i = 0; i <= maxi; i++)
{
if (client[i] < 0)
continue;
sock_fd = client[i];
write(sock_fd, str, strlen(str));
write(sock_fd, " say: ", 6);
n = write(sock_fd, buf, strlen(buf));
if(n == -1)
{
perror( "Write error.\n ");
exit(1);
}
}
for(i = 0; i < MAXLINE; i++)
buf[i] = '\0 ';
}
if (--nready <= 0)
break;
} //if
} //for
} //for
}


加*号的是问题所在,这是一个聊天室的服务端,假如第一个客户的IP是192.168.0.66,那么*号所在行打出的信息也是正确的,如果第二个客户的IP是192.168.0.91,那么打出的信息也会是第二个的,但问题是,如果第一个客户再打信息,服务器输出的IP还是0.91,自己看了两天没找出个正确能显示自己IP的方法,求高人指点,看能解决这个问题吗?
请指出问题所在,非常非常感谢

[解决办法]
为什么inet_ntop(AF_INET,&pin.sin_addr,str,sizeof(str))都不能正确显示对方来的IP呢
这个函数不就是把对方的IP转到str里的吗?任何来的IP都会转 的啊,直是奇怪
[解决办法]
++++++++++
int j = sizeof( pin );
getpeername( sock_fd, (struct sockaddr*)(&pin), &j );
++++++++++++++++

inet_ntop (AF_INET, &pin.sin_addr, str, *****sizeof*****(str));
printf ( "---IP:%s\n ", str);
[解决办法]
楼上正解,
主要是你的pin变量保存的是最后一次登陆的用户的地址信息,你每此打印都是如此.
楼上的方法是根据sock_fd,从连接里取去对方的地址.
如果不想这样,可以在accept后,把对方的地址用个数组存起来.

读书人网 >C语言

热点推荐