想实现一个程序 UDP例程的。 实现2个客户端通信, 而不是客户端于服务器的通信,大家帮忙想下怎么写啊。下面是我写的客户端和服务器的通信。 服务器作为中转数据

hulunizai 2011-06-24 02:39:07
/* server.c*/

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>

#define LISTENQ 5
#define MAXLINE 512
#define max(x,y) (((x)>(y))?(x):(y))

int main()
{
int sockfd;
int size;
int nbytes;
struct sockaddr_in servaddr;
char message[MAXLINE];
char sndbuff[MAXLINE];
fd_set infds;
int maxfd;

/*创建套接字*/
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0){
printf("Socket created failed\n");
return -1;
}

/*填充socket_in 结构*/
servaddr.sin_family = AF_INET;
servaddr.sin_port=htons(6666);
servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
if (bind(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0){
printf("bind failed\n");
return -1;
}

size = sizeof(servaddr);

while(1){
FD_ZERO(&infds);
FD_SET(fileno(stdin),&infds);
FD_SET(sockfd,&infds);
maxfd=max(fileno(stdin),sockfd)+1;

if (select(maxfd,&infds,NULL,NULL,NULL)==-1){
printf("select io error\n");
return -1;
}

/*如果scoket io 准备好了*/
if (FD_ISSET(sockfd,&infds)){
nbytes = recvfrom(sockfd, message, MAXLINE, 0, (struct sockaddr*)&servaddr, &size);
if (nbytes < 0){
printf("recvfrom(server) failed.\n");
return -1;
}
else{
message[nbytes]=0;
printf("receive message from %s %s", inet_ntoa(servaddr.sin_addr.s_addr), message);
}
}

/*如果是输入IO 准备好了*/
if (FD_ISSET(fileno(stdin),&infds)){
if (fgets(sndbuff, MAXLINE, stdin) == NULL){
return -1;
}
nbytes = sendto(sockfd, sndbuff, sizeof(sndbuff), 0, (struct sockaddr*)&servaddr, size);
if (nbytes < 0){
printf("sendto(server) failed.\n");
return -1;
}
}

}

close(sockfd);

return 0;
}

/*client.c*/

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>

#define LISTENQ 5
#define MAXLINE 512
#define max(x,y) (((x)>(y))?(x):(y))

int main()
{
int sockfd;
int nbytes;
struct sockaddr_in servaddr;
char message[MAXLINE];
char sndbuff[MAXLINE];
fd_set infds;
int maxfd;

/*创建套接字*/
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0){
printf("Socket created failed\n");
return -1;
}

/*填充socket_in 结构*/
servaddr.sin_family = AF_INET;
servaddr.sin_port=htons(6666);
servaddr.sin_addr.s_addr=htonl(INADDR_ANY);

while(1){
FD_ZERO(&infds);
FD_SET(fileno(stdin),&infds);
FD_SET(sockfd,&infds);
maxfd=max(fileno(stdin),sockfd)+1;

if (select(maxfd,&infds,NULL,NULL,NULL)==-1){
printf("select io error\n");
return -1;
}

/*如果scoket io 准备好了*/
if (FD_ISSET(sockfd,&infds)){
nbytes = recvfrom(sockfd, message, MAXLINE, 0, NULL, NULL);
if (nbytes < 0){
printf("recvfrom(server) failed.\n");
return -1;
}
else{
message[nbytes]=0;
printf("receive message from server %s", message);
}
}

/*如果是输入IO 准备好了*/
if (FD_ISSET(fileno(stdin),&infds)){
if (fgets(sndbuff, MAXLINE, stdin) == NULL){
return -1;
}
nbytes = sendto(sockfd, sndbuff, sizeof(sndbuff), 0, (struct sockaddr*)&servaddr, sizeof(servaddr));
if (nbytes < 0){
printf("sendto(server) failed.\n");
return -1;
}
}

}

close(sockfd);

return 0;
}

有个问题弄不明白, 我开了3个终端, 一个运行服务器 两个运行客户端
不同的客户端发送数据到服务器 服务器响应的数据返回给客户端, 但是不会出现紊乱, 好奇怪。 因为在server里面只有1个socket套接字, 都是往这个socket里面写数据, 为什么会那么准确的发送的不同的客户端呢。 就是客户端1 给服务器发送数据, 服务器发送数据会写入到客户端1, 而不会发送到客户端2. 为什么呢?

...全文
368 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
laiyongcai 2012-08-08
  • 打赏
  • 举报
回复
楼主写出来没有(两个客户端之间的通讯),贴出来吧,给大家参考参考!
呆子毛 2011-07-13
  • 打赏
  • 举报
回复
当server收到client1发过来的数据的时候同时也获得client1的IP与port, client2也一样,主要的是client1和client2的port是不一样的,如果把client1和client2是两个住户,如果IP相同说明他们两住在同一条街上,port就是他们家的房屋编号,server就是port来区分的, 所以server不会发错的。
nehc 2011-07-02
  • 打赏
  • 举报
回复
严格意思上说:UPD 没有客户端,服务器之分的 !!

你可以给每个“客户端” bind() IP 和 port

这样每个“客户端”就可以 即当“客户端” 又当“服务器”用了

这个类似于 飞秋 , 貌似它就是这么干的
yuanzhenhai 2011-07-02
  • 打赏
  • 举报
回复
写个链表保存对应的IP与端口号
hefa880 2011-07-01
  • 打赏
  • 举报
回复
认同 无知者无畏 的观点~~
hefa880 2011-07-01
  • 打赏
  • 举报
回复
按照你的意思,A-是客户端,B-客户端,S-是服务器,在你服务器的代码里,并没有向A,B转发的功能,

只是将接收到的信息返回到原来请求方,也就是说有谁请求,你的服务器就响应谁。

如果你A要求服务器中转到B,你服务器必须知道知道B的地址与端口。下面给你两个思路,仅供参考:

思路1:在A组包的时候,加上B的IP及端口给服务器发过去,再在服务器中提取B的IP及端口,然后在服务器组包,由服务器给B发包。但是样必须要给B绑定端口,这样做似太麻烦了,而且扩展性不好。

思路2:服务器在响应时判断,将收到A的包转发给存活的B,这个要服务器进行监听,将监听到B的IP及端口当作回应的发送对象。这个应该会比较好点~~

您可以试试看
无知者无谓 2011-06-30
  • 打赏
  • 举报
回复
没看你的代码
A和B机器要进行UDP通讯,那么谁先发起的呢?发起方必须知道对方的IP和端口,但是自己要用哪个端口来连接对方呢?为了避免这个问题,才有了服务端的说法。而客户端是不能确定自己端口的先发起连接的一方,如果通讯两方都是“客户端”,是无法建立连接的。
你的问题是你没抓到问题的要点,如果你去查NAT穿透、P2P之类的东西会发现对你很有用的。
p2p中服务器的作用就是让2个客户端之间相互“认识”,服务端本身并不给他们作“数据”中转,我想这就是你想要的东西吧?
hulunizai 2011-06-30
  • 打赏
  • 举报
回复
套接字描述符的作用
接收一个客户端连接,生成一个与之对应的套接字描述符,该描述符唯一,服务器发数据以该描述符为依据进行发送

这个是UDP连接啊, 只有1个套接字, 并没有监听套接字和链接套接字啊
翔云123456 2011-06-25
  • 打赏
  • 举报
回复
套接字描述符的作用
接收一个客户端连接,生成一个与之对应的套接字描述符,该描述符唯一,服务器发数据以该描述符为依据进行发送
justkk 2011-06-24
  • 打赏
  • 举报
回复
客户端发送给服务器的报文里面有客户端的地址与端口

4,436

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 内核源代码研究区
社区管理员
  • 内核源代码研究区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧