想实现一个程序 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. 为什么呢?

...全文
373 10 打赏 收藏 转发到动态 举报
AI 作业
写回复
用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,465

社区成员

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

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