server.c -> always recv client data(use poll() to confirm whether an error occurred)
client.c -> always send data to server
I exec server.c and client.c ,then i try to kill client.c process.
But the POLLERR flag never be set.
The man page only say
POLLERR Error condition (output only)
When does Poll() return POLLERR?
What did I miss?
Thanks.
server.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <errno.h>
int main()
{
int rc = 0;
char str[100];
char test[5];
int listen_fd, comm_fd;
struct sockaddr_in servaddr;
struct pollfd fds[200];
listen_fd = socket(AF_INET, SOCK_STREAM, 0);
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htons(INADDR_ANY);
servaddr.sin_port = htons(22000);
bind(listen_fd, (struct sockaddr *) &servaddr, sizeof(servaddr));
listen(listen_fd, 10);
comm_fd = accept(listen_fd, (struct sockaddr*) NULL, NULL);
fds[0].fd = comm_fd;
fds[0].events = POLLIN | POLLOUT | POLLERR | POLLHUP;
printf("start\n");
while(1) {
rc = poll(fds,1,1000);
if (rc < 0)
printf("failed\n");
else if(rc==0)
printf("timeout\n");
else {
if (fds[0].revents & POLLERR){
printf("Error!!\n");
}
if(fds[0].revents & POLLHUP){
printf("handup!!\n");
break;
}
if (fds[0].revents & POLLIN){
int bl = recv(comm_fd,test,4,0);
printf("recv:%s %d\n",test,bl);
}
}
sleep(1);
}
return 0;
}
client.c
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
int main(int argc,char **argv)
{
int sockfd,n;
char sendline[100];
char recvline[100];
struct sockaddr_in servaddr;
sockfd=socket(AF_INET,SOCK_STREAM,0);
bzero(&servaddr,sizeof servaddr);
servaddr.sin_family=AF_INET;
servaddr.sin_port=htons(22000);
inet_pton(AF_INET,"127.0.0.1",&(servaddr.sin_addr));
connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
while(1){
send(sockfd,"test",4,0);
sleep(5);
}
close(sockfd);
return 0;
}
It's implementation dependent. Most applications just treat POLLERR the same as normal readiness, allowing the subsequent operation to fail.
Related
I am trying to broadcast a UDP message from the server to client. I would like for the server to send the broadcast to the client and then for the client to acknowledge the broadcast. They both compile with no errors but the server will not send the broadcast. The server says it successfully binds. Any tips would be helpful please.
Client.c
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <arpa/inet.h>
#define PORT 8081
int main (int argc, char* argv[]){
int clientsocket;
int reuse = 1;
int reuseaddr;
int bind_sock;
int rec_broad;
int send_ack;
char dgram[512];
char client_message[2000];
struct sockaddr_in serv_address;
struct sockaddr_in group;
if (argc != 3) {
printf("Command line args should be multicast group and port\n");
printf("(e.g. for SSDP, `listener 239.255.255.250 1900`)\n");
return 1;
}
clientsocket = socket(AF_INET, SOCK_DGRAM, 0);
if(clientsocket < 0){
printf("\n\tSocket not created.\n");
exit(1);
}
else printf("\n\tSocket created successfully.\n");
reuseaddr = setsockopt(clientsocket, SOL_SOCKET, SO_REUSEADDR, (char*)&reuse, sizeof(reuse));
if(reuseaddr < 0){
printf("\n\tSetting REUSEADDR error.\n");
exit(1);
}
else printf("\n\tREUSEADDR Successful.\n");
serv_address.sin_family = AF_INET;
serv_address.sin_port = htons(PORT);
serv_address.sin_addr.s_addr = inet_addr(argv[1]);
/*bind_sock = bind(clientsocket, (struct sockaddr*) &serv_address, sizeof(serv_address));
if(bind_sock < 0){
printf("\n\tBind unsuccessful.\n");
exit(1);
}
else printf("\n\tBind Successful.\n");*/
strcpy(client_message, "Acknowledged.\n");
for(;;){
printf("\nListening........\n");
rec_broad = recvfrom(clientsocket, dgram, sizeof(dgram), 0, (struct sockaddr*) &serv_address, sizeof(serv_address));
if(rec_broad < 0){
printf("\n\tBroadcast not received.\n");
exit(1);
}
else printf("\n\tBroadcast received successfully.\n");
send_ack = sendto(clientsocket, client_message, sizeof(client_message), 0, (struct sockaddr*)&serv_address, sizeof(serv_address));
if (send_ack < 0){
printf("\n\tAck not sent.\n");
}
else printf("\n\tAcknowledge sent successfully.\n");
}
return 0;
}
Server.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define PORT 8081
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
int main (int argc, char *argv[]){
int serv_socket;
struct sockaddr_in broadcast_addr;
struct sockaddr_in client_addr;
int b_addr_len;
int ret;
int bind_sock;
int yes = 1;
char buffer[2000];
int send_broad;
int z;
//Create socket
serv_socket = socket(AF_INET, SOCK_DGRAM, 0);
if(serv_socket < 0){
printf("\n\tProblem1.\n");
exit(1);
}
else printf("\n\tSocket made successful.\n");
//Setsockopt
ret = setsockopt(serv_socket, SOL_SOCKET, SO_BROADCAST, (char*)&yes, sizeof(yes));
if(ret < 0){
printf("\n\tSetsockopt error.\n");
return -1;
}
else printf("\n\tSetsockopt successful.\n");
b_addr_len = sizeof(broadcast_addr);
//Broadcast Address
memset((void*)&broadcast_addr, 0, b_addr_len);
broadcast_addr.sin_family = AF_INET;
broadcast_addr.sin_addr.s_addr = inet_addr(argv[1]);
broadcast_addr.sin_port = htons(atoi(argv[2]));
//Bind socket with client
bind_sock = bind(serv_socket, (struct sockaddr*) &client_addr, b_addr_len);
if (ret < 0){
printf("\n\tBind unsuccessful.\n");
exit(1);
}
else printf("\n\tBind successful.\n");
memset(buffer, '\0', 2000);
strcpy(buffer, "This is the broadcast!\n");
//Send broadcast
send_broad = sendto(serv_socket, buffer, sizeof(buffer), 0, (struct sockaddr*)&broadcast_addr, b_addr_len);
if(send_broad < 0){
printf("\n\tBroadcast not sent.\n");
exit(1);
}
else printf("\n\tBroadcast sent OK.\n");
return 0;
}
So i am following the book of UNIX network programming, and tried to write a simple daytime server from chapter 1 and client but the bind function is always returning an error, what I'm doing wrong can anyone help??
server.c
/*
* Daytime Server
*/
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <arpa/inet.h>
void printError(char *str)
{
printf("%s", str);
exit(0);
}
int main(int argc, char **argv)
{
int listenfd, connfd;
struct sockaddr_in servaddr;
char buff[4096];
time_t ticks;
if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printError("Error at line 32 socket fuct.");
}
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(13);
if (bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
{
printError("Error at bind function");
}
if (listen(listenfd, 1024) < 0)
{
printError("Error at listen fuct.");
}
while (1)
{
if ((connfd = accept(listenfd, (struct sockaddr *)NULL, NULL)) < 0)
{
printError("Error at accept fuct.");
}
ticks = time(NULL);
snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
if (write(connfd, buff, strlen(buff)) < 0)
{
printError("Error at write fuct.");
}
close(connfd);
}
return EXIT_SUCCESS;
}
client.c
/*
* Daytime Client
*/
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
void printError(char *str)
{
printf("%s", str);
exit(0);
}
int main(int argc, char **argv)
{
int socketfd, n;
char recvline[4097];
struct sockaddr_in servaddr;
if (argc != 2)
{
printError("Requires ip address of the server");
}
if ((socketfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printError("Unable to create a Connection");
}
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_port = htons(13);
servaddr.sin_family = AF_INET;
if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
{
printError("Not valid IP");
}
if (connect(socketfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
{
printError("Connection Error");
}
while ((n = read(socketfd, recvline, 4096)) > 0)
{
recvline[n] = 0;
if (fputs(recvline, stdout) == EOF)
{
printError("Fputs Error");
}
}
if (n < 0)
{
printError("Not readable");
}
return EXIT_SUCCESS;
}
Running server is always returning -1 on bind function. and running client always prints connection error.
Thank you in advance for help.
You should check with errno to find out WHY bind() is failing when it returns -1. You can use perror() to print a human-readable description of errno to the console, or at least strerror() to get that description in a string buffer that you can then do whatever you want with.
But the most likely reason for WHY bind() is failing is that you are trying to bind() your server to port 13. On most systems, ports 0-1023 are reserved for system services, so you would need to run your app with admin rights to listen on those ports.
I recently made a server client program in c but it doesn't seem to work. the only thing i get when compiling it is a warning and the fact that there is a fault in the client. Could anyone help me a bit?
This is the server code:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main()
{
int server_socket;
server_socket = socket(AF_INET,SOCK_STREAM,0);
struct sockaddr_in server_address;
int addrlen = sizeof(server_address);
server_address.sin_family = AF_INET;
server_address.sin_port = htons(9000);
server_address.sin_addr.s_addr = INADDR_ANY;
bind (server_socket, (struct sockaddr*) &server_address, sizeof(server_address));
int client_socket;
listen(server_socket, 3);
client_socket=accept(server_socket, NULL, (socklen_t*)&addrlen);
char response[256];
recv(server_socket, &response, sizeof(response), 0);
printf("%s",response);
pclose (server_socket);
return (0);
}
and this is the client code:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main()
{
int network_socket;
network_socket = socket(AF_INET,SOCK_STREAM, 0);
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(9000);
server_address.sin_addr.s_addr = INADDR_ANY;
int connection_status = connect(network_socket, (struct sockaddr*)&server_address, sizeof(server_address));
if (connection_status == -1) { printf("ERROR"); }
char maw[256] = "this is a message"; send(network_socket, maw, sizeof(maw), 0); close(server_address);
return(0);
pclose(network_socket);
}
There is also an error in the server code.
Server code:
When you want to receive the message from the client, you must use the client_socket in your code in the recv() function. Not the server_socket itself.
Client code:
Why you are using the pclose() function, for closing the socket? It's for pipes and requires a FILE pointer. Furthermore the function never get called (after return statement).
This should work (tested on my system):
Server:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main()
{
int server_socket;
server_socket = socket(AF_INET,SOCK_STREAM,0);
struct sockaddr_in server_address;
int addrlen = sizeof(server_address);
server_address.sin_family = AF_INET;
server_address.sin_port = htons(9000);
server_address.sin_addr.s_addr = INADDR_ANY;
bind (server_socket, (struct sockaddr*) &server_address, sizeof(server_address));
int client_socket;
listen(server_socket, 3);
client_socket=accept(server_socket, NULL, (socklen_t*)&addrlen);
char response[256];
recv(client_socket, &response, sizeof(response), 0);
printf("%s",response);
shutdown (client_socket, SHUT_RDWR);
close (client_socket);
shutdown (server_socket, SHUT_RDWR);
close (server_socket);
return (0);
}
Client:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main()
{
int network_socket;
network_socket = socket(AF_INET,SOCK_STREAM, 0);
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(9000);
server_address.sin_addr.s_addr = INADDR_ANY;
int connection_status = connect(network_socket, (struct sockaddr*)&server_address, sizeof(server_address));
if (connection_status == -1) { printf("ERROR"); }
char maw[256] = "this is a message";
send(network_socket, maw, sizeof(maw), 0);
shutdown (network_socket, SHUT_RDWR);
close(network_socket);
return(0);
}
For the function shutdown() see this answer.
I am trying to check if a specific UDP port is open or not. I am trying to do this by sending UDP packets and checking the ICMP response to see if the UDP port is avaiable or not. What am I doing wrong?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <pthread.h>
#include <arpa/inet.h> /* inet(3) functions */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <netdb.h>
#include <unistd.h>
#include <sys/time.h>
#include <stdio.h>
#include <errno.h>
#define MAXLINE 10096
int main(int argc, char **argv)
{
int sockfd, portno;
struct sockaddr_in servaddr;
struct hostent *server;
int sendfd, recvfd;
server = gethostbyname(argv[1]);
if (server == NULL)
{
fprintf(stderr,"ERROR, no such host\n");
exit(EXIT_FAILURE);
}
//socket varibles
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
bcopy((char *)server->h_addr, (char *)&servaddr.sin_addr.s_addr, server->h_length);
//get port from command line arguments
portno = atoi(argv[2]);
servaddr.sin_port = htons(portno);
inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
// open send UDP socket
if((sendfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
{
perror("*** socket(,,IPPROTO_UDP) failed ***n");
exit(-1);
}
// open receive ICMP socket
if((recvfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0)
{
perror("*** socket(,,IPPROTO_ICMP) failed ***n");
exit(-1);
}
int n;
char sendline[] = "a message"; //string for message to be sent
char recvline[MAXLINE]; //string for message to be received
//send ping request
if(sendto(sendfd, sendline, sizeof(sendline), 0, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0)
{
perror("*** sendto() failed ***");
}
struct timeval tv;
tv.tv_sec = 1;
tv.tv_usec = 100000;
if (setsockopt(recvfd, SOL_SOCKET, SO_RCVTIMEO,&tv,sizeof(tv)) < 0) {
perror("Error");
}
n = recvfrom(recvfd, recvline, MAXLINE, 0, NULL, NULL);
recvline[n] = '\0'; /* null terminate */
struct iphdr *ip_hdr = (struct iphdr *)recvline;
int iplen = ip_hdr->ihl << 2;
struct icmphdr *icmp = (struct icmphdr *)((char *)ip_hdr + (4 * ip_hdr->ihl));
if((icmp->type == ICMP_UNREACH) && (icmp->code == ICMP_UNREACH_PORT))
{
printf("\nPORT CLOSED\n");
}
else
{
printf("\nPORT OPEN\n");
}
exit(0);
}
How can I get this working? When I run the code, It always says "PORT OPEN" in every port I test it with which definitely cannot be right.
Excuse my long post. I would post code so that it is easier to understand the problem I am facing. It seems that if a signaled socket is added to epoll instance, epoll_wait on the epoll instance will not block. The following example has let me believe this:
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
#include <sys/epoll.h>
int MAX_EVENT_COUNT = 10;
int main(int argc, char *argv[])
{
int epollfd = epoll_create( MAX_EVENT_COUNT );
if ( epollfd == -1 )
{
printf("\n Error : epoll_create \n");
return 1;
}
epoll_event ev;
memset(&ev,0,sizeof(ev));
ev.events = EPOLLIN | EPOLLET;
int pipefd[2];
if (pipe(pipefd) == -1)
{
perror("pipe");
exit(EXIT_FAILURE);
}
char ch = 'a';
write(pipefd[1], &ch, 1);
if (epoll_ctl( epollfd , EPOLL_CTL_ADD, pipefd[0], &ev ) == -1 )
{
printf("\n Error : epoll add result \n");
return 1;
}
epoll_event rawResult [MAX_EVENT_COUNT];
int32_t res = epoll_wait( epollfd, rawResult, MAX_EVENT_COUNT, -1 );
if(res!=1)
{
printf("\n Epoll problem \n");
}
else
{
printf("\n OK \n");
}
}
However the following example is pretty much the same but this time I add a signalled socket to the epoll, this time the epoll_wait call blocks
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
#include <sys/epoll.h>
int MAX_EVENT_COUNT = 10;
int main(int argc, char *argv[])
{
int listenfd = 0;
{
struct sockaddr_in serv_addr;
char sendBuff[1025];
listenfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&serv_addr, '0', sizeof(serv_addr));
memset(sendBuff, '0', sizeof(sendBuff));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(5000);
bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
listen(listenfd, 10);
}
int sockfd = 0, n = 0;
char recvBuff[1024];
struct sockaddr_in serv_addr;
memset(recvBuff, '0',sizeof(recvBuff));
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Error : Could not create socket \n");
return 1;
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(5000);
if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0)
{
printf("\n inet_pton error occured\n");
return 1;
}
if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\n Error : Connect Failed \n");
return 1;
}
int connfd = accept(listenfd, (struct sockaddr*)NULL, NULL);
int epollfd = epoll_create( MAX_EVENT_COUNT );
if ( epollfd == -1 )
{
printf("\n Error : epoll_create \n");
return 1;
}
epoll_event ev;
memset(&ev,0,sizeof(ev));
ev.events = EPOLLIN | EPOLLET;
if (epoll_ctl( epollfd , EPOLL_CTL_ADD, sockfd, &ev ) == -1 )
{
printf("\n Error : epoll add result \n");
return 1;
}
epoll_event rawResult [MAX_EVENT_COUNT];
int32_t res = epoll_wait( epollfd, rawResult, MAX_EVENT_COUNT, -1 );
}
epoll_wait() will block if the file descriptors it is waiting on have no events for it to report about. In your case, I don't believe you have reached epoll_wait() yet. Assuming that your program has progressed passed connect() and accept(), then you have not written any data on the connection (on the sockfd), so epoll_wait() will not detect any events on the connfd.
This is different from your first program, where you write a byte of data on the pipefd[1] before calling epoll_wait() on pipefd[0].