[英]Sockets, client server communication using SOCK_DGRAM, epoll
I'm trying to write a program with AF_INET, SOCK_DGRAM, where client connects to server sends it message "First message"
and then the server responds to client with "Second message"
. 我正在尝试使用AF_INET,SOCK_DGRAM编写程序,客户端连接到服务器时会向其发送消息
"First message"
,然后服务器会使用"Second message"
来响应客户端。
Q1: In my code server receives "First message"
, however client doesn't get server response "Second message"
, why? Q1:我的代码服务器中收到
"First message"
,但是客户端没有得到服务器响应"Second message"
,为什么?
Q2: In client I connect to server using msg_addr.sin_addr.s_addr =INADDR_ANY;
Q2:在客户端中,我使用
msg_addr.sin_addr.s_addr =INADDR_ANY;
连接到服务器msg_addr.sin_addr.s_addr =INADDR_ANY;
I would like to change it for something like: msg_addr.sin_addr.s_addr =htonl(inet_addr("172.126.154.12"));
我想将其更改为:
msg_addr.sin_addr.s_addr =htonl(inet_addr("172.126.154.12"));
where ip "172.126.154.12"
is server ip; 其中ip
"172.126.154.12"
是服务器ip;
server.c server.c
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <arpa/inet.h>
#include <sys/epoll.h>
#include <errno.h>
#include <signal.h>
#include <string.h>
typedef struct{
int type;
int arg1;
int arg2;
int result;
char name[50];
}Msg;
#define WRITE(format, ...) { char buffer[255]; sprintf(buffer, format, ##__VA_ARGS__); write(1, buffer, strlen(buffer));}
#define FAILURE_EXIT(format, ...) { char buffer[255]; sprintf(buffer, format, ##__VA_ARGS__); write(1, buffer, strlen(buffer));exit(-1);}
int web_fd, epoll;
struct sockaddr_in server_addr;
Msg msg;
struct sockaddr msg_addr;
int main(int argc, char *argv[]){
if((web_fd = socket(AF_INET, SOCK_DGRAM,0)) == -1) FAILURE_EXIT("Failed to create communication endpoint web_fd\n");
int yes=1;
if (setsockopt(web_fd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(yes)) == -1) FAILURE_EXIT("setsockopt web_fd\n");
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(9992);
server_addr.sin_addr.s_addr = INADDR_ANY;
if(bind(web_fd,(const struct sockaddr*) &server_addr,sizeof(struct sockaddr)) == -1) FAILURE_EXIT("Failed to assign server_addr to a web_fd: %s\n",strerror(errno));
epoll = epoll_create1(0);
if(epoll == -1) FAILURE_EXIT("Failed to create new epoll instance: %s\n",strerror(errno));
struct epoll_event event;
event.events = EPOLLIN;
event.data.fd = web_fd;
if(epoll_ctl(epoll,EPOLL_CTL_ADD,web_fd,&event)== -1) FAILURE_EXIT("Failed to register web_fd file descriptor on epoll instance: %s\n",strerror(errno));
printf("Server starts loop.\n");
while(1){
struct epoll_event event;
WRITE("Waiting for client message...\n");
int nfd = epoll_wait(epoll,&event,1,-1);
if(event.data.fd == web_fd){
recvfrom(event.data.fd,&msg,sizeof(Msg),0 ,&msg_addr,0);
WRITE("Received message from client %s\n",msg.name);
strcpy(msg.name,"Second message");
sendto(event.data.fd,&msg,sizeof(Msg),0 ,(struct sockaddr*)&msg_addr, (socklen_t) sizeof(msg_addr) );
}else{
WRITE("Unknown descriptor\n");
}
}
}
client.c client.c
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <arpa/inet.h>
#include <sys/epoll.h>
#include <errno.h>
#include <signal.h>
#include <string.h>
typedef struct{
int type;
int arg1;
int arg2;
int result;
char name[50];
}Msg;
#define WRITE(format, ...) { char buffer[255]; sprintf(buffer, format, ##__VA_ARGS__); write(1, buffer, strlen(buffer));}
#define FAILURE_EXIT(format, ...) { char buffer[255]; sprintf(buffer, format, ##__VA_ARGS__); write(1, buffer, strlen(buffer));exit(-1);}
int socket_fd;
struct sockaddr_in msg_addr;
Msg msg;
int main(int argc, char *argv[]){
struct sockaddr_in msg_addr;
msg_addr.sin_family = AF_INET;
msg_addr.sin_addr.s_addr =INADDR_ANY;
msg_addr.sin_port = htons(9992);
socket_fd = socket(AF_INET, SOCK_DGRAM,0);
if(socket_fd == -1) FAILURE_EXIT("Failed to create client socket\n");
if(connect(socket_fd, (const struct sockaddr*) &msg_addr, sizeof(struct sockaddr)) == -1) FAILURE_EXIT("Failed to assign server_addr to a web_fd: %s\n",strerror(errno));
strcpy(msg.name,"First message ");
sendto(socket_fd,&msg,sizeof(Msg),0 ,(struct sockaddr*)&msg_addr,(socklen_t) sizeof(Msg));
WRITE("Waiting..\n");
recvfrom(socket_fd,&msg,sizeof(Msg),0 ,0,0);
WRITE("f %s\n",msg.name);
WRITE("I registered\n");
sleep(400);
}
In server code change recvfrom() call as this 在服务器代码中更改recvfrom()调用如下
socklen_t addrsize;
recvfrom(event.data.fd,&msg,sizeof(Msg),0 ,&msg_addr, &addrsize);
and change subsequent sendto() call as this 并以此更改后续的sendto()调用
sendto(event.data.fd,&msg,sizeof(Msg),0 ,(struct sockaddr*)&msg_addr, addrsize);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.