I have a server that is supposed to send information to a client after receiving a message from the client (echo server). Below is the code that is producing an errno 22 which i looked up as "invalid argument". I am trying to understand which argument is invalid because my client sends a message with the same arguments
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
//#include <sys/time.h>
int main(int argc, char *argv[]) {
// port to start the server on
int SERVER_PORT = 8877;
struct timeval server_start, client_start;
// socket address used for the server
struct sockaddr_in server_address;
memset(&server_address, 0, sizeof(server_address));
server_address.sin_family = AF_INET;
// htons: host to network short: transforms a value in host byte
// ordering format to a short value in network byte ordering format
server_address.sin_port = htons(SERVER_PORT);
// htons: host to network long: same as htons but to long
server_address.sin_addr.s_addr = htonl(INADDR_ANY);
// create a UDP socket, creation returns -1 on failure
int sock;
if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
printf("could not create socket\n");
return 1;
}
// bind it to listen to the incoming connections on the created server
// address, will return -1 on error
if ((bind(sock, (struct sockaddr *)&server_address,
sizeof(server_address))) < 0) {
printf("could not bind socket\n");
return 1;
}
// socket address used to store client address
struct sockaddr_in client_address;
int client_address_len = 0;
// run indefinitely
while (true) {
char buffer[500];
printf("problem here \n");
int len=0;
// read content into buffer from an incoming client
if (len = recvfrom(sock, &client_start, sizeof(client_start), 0,(struct sockaddr *)&client_address,&client_address_len)<0){
printf("failed: %d\n", errno);
return 1;
}
// inet_ntoa prints user friendly representation of the
// ip address
//buffer[len] = '\0';
gettimeofday(&server_start);
int send = 0;
// send same content back to the client ("echo")
if(send = sendto(sock, &server_start, sizeof(server_start),0,(struct sockaddr *)&client_address,
&client_address_len)<0){
printf("failed: %d\n", errno);
return 1;
};
}
return 0;
}
I am trying to understand which argument is invalid
No argument is invalid. You got a false positive on your error testing.
if (len = recvfrom(sock, &client_start, sizeof(client_start), 0,(struct sockaddr *)&client_address,&client_address_len)<0){
if(send = sendto(sock, &server_start, sizeof(server_start),0,(struct sockaddr *)&client_address,
&client_address_len)<0){
Usual problem. Operator precedence. Try this:
if ((len = recvfrom(sock, &client_start, sizeof(client_start), 0,(struct sockaddr *)&client_address,&client_address_len))<0){
if((send = sendto(sock, &server_start, sizeof(server_start),0,(struct sockaddr *)&client_address,
&client_address_len))<0){
Related
I have such a task, I need to write the “client” code so that the message from the “client” is sent to the server (which was created by my teacher, ip “127.0.0.1”). After the message arrives at the server (for example, “Nursultan Nazarbayev”, the server will reply “ok” and the client should send “quit”)
I'm just learning C. How to make a break with the server? I wanted to send "quit", but this did not work, there was a constant error, how can I do this?
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char **argv)
{
char message[2048];//=(char*)malloc(sizeof(char));// transmission message
char buf[sizeof(message)];
int port,ch;
//----------------------------------------------------------------------------
if(argc!=3){
printf("Wrong number of arguments!\nThere must be 2 arguments (Port, server ip-address)!\n");
exit(0);
}
int sock; // socket descriptor
struct sockaddr_in addr; // structure with address
struct hostent* hostinfo;
port = atoi(argv[1]);
hostinfo = argv[2];
sock = socket(AF_INET, SOCK_STREAM, 0); // create TCP socket
if(sock < 0)
{
perror("socket");
exit(1);
}
// Specify server parameters
addr.sin_family = AF_INET; // Internet domains
addr.sin_port = htons(port); // or any other port ...
addr.sin_addr.s_addr=inet_addr("hostinfo");
// addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
//addr.sin_addr.s_addr = inet_addr(host_ip);
if(connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) // establishing a connection to the server
{
perror("Connection");
exit(2);
}
while(1){//WHILE <---
//----------------------------------------------------------------------------
printf("Enter a message to the server (To exit: quit): ");
if (!strcmp(gets(message), "quit")){close(sock);return 0;}
//----------------------------------------------------------------------------
printf("sending a message to the server...\n");
send(sock, message, sizeof(message), 0); // sending a message to the server
int bytes_read = 0;
printf("Message Waiting\n");
bytes_read = recv(sock, buf, sizeof(message), 0);
printf("received %d bytes\tMessage: %s\n", bytes_read, buf); // receiving a message from the server
}//END_WHILE
return 0;
}
This probably is wrong:
addr.sin_addr.s_addr=inet_addr("hostinfo");
You are passing the literal string, "hostinfo" to the inet_addr() function. Meanwhile, you have a variable named hostinfo, to which you assign a string value, but you never use it anywhere in the program.
Maybe you meant to do this instead:
addr.sin_addr.s_addr=inet_addr(hostinfo);
P.S., I like long, descriptive names. If that was my program, the name of the variable would be something like, server_address_as_string.
TCP socket demultiplexing at the server port (which listens for multiple TCP connections) happens with a separate socket descriptor created for each established TCP connection(though the accept() call) and the socket descriptor is tightly coupled with tuple [source IP address, source port, destination IP address, destination IP address]. Over this established connection we can use the high layer application protocols like HTTP, FTP, SSH etc.,
But in case of UDP there is no session/connection established between the peers. The server waiting at the particular port receives the message from any client. The client's IP address and port number is known after receiving the message(populated in the socket address structure). From the address structure the messages can be demultiplexed and given to respective applications.
Over the server port, If I want to establish a connected session over UDP[like the tuple mentioned in case of TCP] so that communication between the server and client (between particular port on server and client) can be demultiplexed before receiving the message(without inferring the same from socket address structure) so that the higher layer protocols can work like on TCP (ofcourse higher layer protocols like DTLS taking care of the reliability)
Below is the code for UDP server(leveraging the connect() API to keep the UDP socket connected) and UDP client
// server program for udp connection
#include <stdio.h>
#include <strings.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PORT 5000
#define MAXLINE 1000
//logical thread num
static unsigned int threadnum = 0;
struct pass_info {
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
unsigned int threadnum;
};
char *message = "Hello Client";
void* connection_handle(void *info) {
int fd = 0;
char buffer[100];
int n = 0;
const int on = 1;
struct pass_info *pinfo = (struct pass_info*) info;
printf("Executing thread : %d\n", pinfo->threadnum);
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0) {
printf("Error socket!!!");
return;
}
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void*) &on, (socklen_t) sizeof(on));
bind(fd, (const struct sockaddr *) &pinfo->server_addr, sizeof(struct sockaddr_in));
connect(fd, (struct sockaddr *) &pinfo->client_addr, sizeof(struct sockaddr_in));
while(1)
{
n = recv(fd, buffer, sizeof(buffer), 0);
if (n < 0)
{
printf("receive failed! in thread : %d", pinfo->threadnum);
break;
}
buffer[n] = '\0';
printf("Thread num %d: Recv message - %s\n", pinfo->threadnum, buffer);
n = send(fd, message, sizeof(message), 0);
if (n < 0)
{
printf("send failed! in thread : %d", pinfo->threadnum);
break;
}
}
free(info);
return NULL;
}
int main()
{
char buffer[100];
int listenfd, len, sockfd;
const int on = 1;
struct sockaddr_in servaddr, cliaddr;
bzero(&servaddr, sizeof(servaddr));
struct pass_info *info;
pthread_t tid;
// Create a UDP Socket
listenfd = socket(AF_INET, SOCK_DGRAM, 0);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(PORT);
servaddr.sin_family = AF_INET;
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (const void*) &on, (socklen_t) sizeof(on));
// bind server address to socket descriptor
bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr));
while (1)
{
//receive the datagram
len = sizeof(cliaddr);
int n = recvfrom(listenfd, buffer, sizeof(buffer),
0, (struct sockaddr*)&cliaddr,&len); //receive message from server
buffer[n] = '\0';
printf("Main thread: Recv message - %s\n", buffer);
n = sendto(listenfd, message, MAXLINE, 0, (struct sockaddr*)&cliaddr, sizeof(cliaddr));
info = (struct pass_info*) malloc (sizeof(struct pass_info));
memcpy(&info->server_addr, &servaddr, sizeof(struct sockaddr_in));
memcpy(&info->client_addr, &cliaddr, sizeof(struct sockaddr_in));
threadnum++;
info->threadnum = threadnum;
if (pthread_create(&tid, NULL, connection_handle, info) != 0) {
perror("pthread_create");
exit(-1);
}
}
}
// udp client program
#include <stdio.h>
#include <strings.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include<netinet/in.h>
#include<unistd.h>
#include<stdlib.h>
#define PORT 5000
#define MAXLINE 1000
int main()
{
char buffer[100];
char *message = "Hello Server";
int sockfd, n;
struct sockaddr_in servaddr, cliaddr;
int len = 0;
// clear servaddr
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
servaddr.sin_port = htons(PORT);
servaddr.sin_family = AF_INET;
// create datagram socket
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
while(1)
{
sleep(3);
sendto(sockfd, message, MAXLINE, 0, (struct sockaddr*)&servaddr, sizeof(servaddr));
// waiting for response
recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr*)&cliaddr, &len);
puts(buffer);
}
}
Queries:
Whether this would be the right way to do de-multiplexing at the UDP socket level
The server listens for any UDP packets from the client. once it receives a message, new socket descriptor is created and the connect() API is called so that the client's IP address, port is registered with this newly created socket descriptor and from here on newly created socket descriptor will used to send and receive messages to the particular client's IP address and port. Whether it is a fool proof method
Are there any other well known methods to use the higher layer protocols(protocols supporting reliability like DTLS) over UDP
I'm trying to implement communication by UDP protocol, and I'm getting an error: "Error sending: Address family not supported by protocol". I've checked in Google for this problem but couldn't managed to find answer.
Please be patient, I'm only starting my adventure with coding in C.
Here is a C code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#define BUFLEN 512
// define function that deals with errors
void error(const char *msg)
{
perror(msg); // print error msg
exit(1); // exit the main() function
}
int main(int argc, char *argv[])
{
struct sockaddr_in serv1_addr, serv2_addr, cli1_addr, cli2_addr; //definicja struktur adresów servera i clienta
struct hostent *server; //defines host addres struct
int cl1_sockfd, se1_sockfd, se2_sockfd, i, c1len = sizeof(cli1_addr), c2len = sizeof(cli2_addr), recv_len, portno1,portno2; // creates inits
int cli1_len = sizeof(cli1_addr);
int cli2_len = sizeof(cli2_addr);
char buf[BUFLEN];
if (argc < 4) {
fprintf(stderr,"ERROR, no port provided\n"); // deal with wrong port
exit(1);
}
//tworzenie soceketu servera
if ((se1_sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1){
error("socket1"); //if socket() return -1 -- error
}
if ((se2_sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1){
error("socket2"); //if socket() return -1 -- error
}
//zero out the structure
memset( &serv1_addr, 0, sizeof(serv1_addr)); //put zero into structure
memset( &serv2_addr, 0, sizeof(serv2_addr)); //put zero into structure
portno1 = atoi(argv[2]); // get port number
portno2 = atoi(argv[3]);
serv1_addr.sin_family = AF_INET; // specify address family (IPv4)
serv1_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
serv1_addr.sin_port = htons(portno1); // set port number
serv2_addr.sin_family = AF_INET; // specify address family (IPv4)
serv2_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
serv2_addr.sin_port = htons(portno2); // set port number
if(connect(se1_sockfd,(struct sockaddr *) &serv1_addr, sizeof(serv1_addr)) < 0)
error ("ERROR connecting1"); //if connection failed
if(connect(se2_sockfd,(struct sockaddr *) &serv2_addr, sizeof(serv2_addr)) < 0)
error ("ERROR connecting2"); //if connection failed
while(1) //inf loop
{
printf("Please enter the message: "); //write the msg to socket
bzero(buf, 512); //fill buffer with zeros
fgets(buf, 512, stdin); //read into buffer
if( sendto( se1_sockfd, buf, BUFLEN, 0, (struct sockaddr*) &cli1_addr, cli1_len) < 0)
error ("Error sending1");
if( sendto( se2_sockfd, buf, BUFLEN, 0, (struct sockaddr*) &cli2_addr, cli2_len) < 0)
error ("Error sending2");
if (recvfrom(se1_sockfd, buf, BUFLEN, 0, (struct sockaddr *) &cli1_addr, &cli1_len) == -1){
error("recivfrom()1"); //if reciving failed -- error
}
printf("Data: %s\n", buf);
if (recvfrom(se2_sockfd, buf, BUFLEN, 0, (struct sockaddr *) &cli2_addr, &cli2_len) == -1){
error("recivfrom()2"); //if reciving failed -- error
}
printf("Data: %s\n", buf);
}
close(se1_sockfd);
close(se2_sockfd);
return 0;
}
Thanks for your help. ;)
Your issue is likely because of uninitialized destination address. sendto() takes destination address as the one before the last argument. But you are trying to provide not-initialized address (like for recvfrom())
if( sendto( se1_sockfd, buf, BUFLEN, 0, (struct sockaddr*) &cli1_addr, cli1_len) < 0)
error ("Error sending1");
^^^
Try serv1_addr instead ?
Also need to provide appropriate size.
One more thing. As long as you use sendto() - no need to perform connect(). UDP is connectionless and connect() only establishes default destination address for those who is going to use send() on such socket. But this is not your case because you provide destination address each time you call sendto(). Even more - you may use different addresses each time.
P.S. Reference: sendto()
I'm trying to write a client server program using UDP, and wait-and-stop, but I haven't got to that part, I'm still trying to figure it out how the two processes (server and client) communicate, because on my client program, the user needs to enter the server name or IP address, and a port name, and then send an expression that the server should calculate. However, I dug some tutorials in the internet and after coding accordingly (or I thought so) I can't make the client communicate with the server. Below is my code, please enlighten me what I'm doing wrong, if it's the bind(), sendto(), recvfrom() or socket(), or all of them. I can't see what exactly is wrong. I know that the client-side shouldn't run on a infinite loop, but so far I want to make the programs communicate with each other, afterwards I'll polish my code. Thanks!
client-side code:
#include <stdio.h> // Default System Calls
#include <stdlib.h> // Needed for OS X
#include <string.h> // Needed for Strlen
#include <sys/socket.h> // Needed for socket creating and binding
#include <netinet/in.h> // Needed to use struct sockaddr_in
#include <time.h> // To control the timeout mechanism
#define EXPR_SIZE 1024
#define BUFLEN 512
#define TRUE 1
#define FALSE 0
#define SERVERLEN 1024
int main(int argc, char **argv){
long portNum; // Since it's possible to input a value bigger
// than 65535 we'll be using long to
// avoid overflows
char expr[EXPR_SIZE];
char server[SERVERLEN];
int fd; // file descriptor for the connected socket
int buf[512];
struct hostent *h; // information of the host
unsigned int addrLen; // address length after getting the port number
struct sockaddr_in myaddr; // address of the client
struct sockaddr_in servaddr; // server's address
unsigned int exprLen;
socklen_t slen = sizeof(servaddr);
printf("Enter server name or IP address:");
scanf("%s",server);
printf("Enter port:");
scanf("%ld",&portNum);
if ((portNum < 0) || (portNum > 65535)) {
printf("Invalid port number. Terminating.");
return 0;
}
printf("Enter expression:");
scanf("%s",expr);
if((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){
perror("cannot create socket");
return 0;
}
memset((char *)&myaddr, 0, sizeof(myaddr));
myaddr.sin_family = AF_INET;
myaddr.sin_addr.s_addr = htonl(INADDR_ANY);
myaddr.sin_port = htons(0);
if(bind(fd, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0){
perror("cannot bind");
return 0;
}
/*
// Discovering the port number the OS allocated
addrLen = sizeof(myaddr);
if(getsockname(fd, (struct sockaddr *)&myaddr, &addrLen) < 0){
perror("cannot getsockname");
return 0;
}
printf("local port number = %d\n", ntohs(myaddr.sin_port));
*/
memset((char*)&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htonl(portNum);
exprLen = sizeof(expr);
while(TRUE){
printf("Sending message to %s port %ld\n",server, portNum);
if (sendto(fd, expr, strlen(expr), 0, (struct sockaddr *)&servaddr, slen) < 0) {
perror("cannot sendto()");
}
printf("Success\n");
}
return 0;
}
Server-side code:
#include <stdio.h> // Default System Calls
#include <stdlib.h> // Needed for OS X
#include <string.h> // Needed for Strlen
#include <sys/socket.h> // Needed for socket creating and binding
#include <netinet/in.h> // Needed to use struct sockaddr_in
#include <time.h> // To control the timeout mechanism
#define EXPR_SIZE 1024
#define BUFLEN 512
#define TRUE 1
#define SERVERLEN 1024
int main(int argc, char **argv){
struct sockaddr_in myaddr; // address of the server
struct sockaddr_in claddr; // address of the client
char buf[BUFLEN];
int fd;
long recvlen;
socklen_t clientlen;
if((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){
perror("cannot create socket");
return 0;
}
memset((char *)&myaddr, 0, sizeof(myaddr));
myaddr.sin_family = AF_INET;
myaddr.sin_addr.s_addr = htonl(INADDR_ANY);
myaddr.sin_port = htons(0);
if(bind(fd, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0){
perror("cannot bind");
return 0;
}
clientlen = sizeof(claddr);
while (TRUE) {
recvlen = recvfrom(fd, buf, BUFLEN, 0, (struct sockaddr *)&claddr, &clientlen);
if (recvlen < 0) {
perror("cannot recvfrom()");
return 0;
}
printf("Received %ld bytes\n",recvlen);
buf[recvlen] = 0;
printf("Received message: \"%s\"\n",buf);
}
return 0;
}
The server program doesn't output anything, while the client outputs until the process is interrupted:
Enter server name or IP address:127.0.0.1
Enter port:30
Enter expression:2+2
Sending message to 127.0.0.1 port 30
cannot sendto(): Can't assign requested address
I tried changing the server name to localhost, and other ports, but to no avail.
When developing networking software (especially when using the BSD socket interface), it's important to keep things as simple as possible until you've established basic communication. Then you can incrementally add functionality, while making sure that you don't break anything along the way.
On the client side, keeping things simple means
Don't call bind in the client. The OS will choose an appropriate interface and assign a random port number, so there's no need to bind the socket.
Use a hard-coded server address (e.g. 127.0.0.1). Address 127.0.0.1 (0x7f000001) is the local host address, suitable for sending packets to a server on the same machine.
Use a hard-coded port number (e.g. 50037). Ephemeral port numbers should be greater than 0xC000 hex (49152 decimal).
Use a hard-coded message, e.g. "hello".
With that in mind, here's what the client software looks like
int main( void )
{
int fd;
if ( (fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
perror("socket failed");
return 1;
}
struct sockaddr_in serveraddr;
memset( &serveraddr, 0, sizeof(serveraddr) );
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons( 50037 );
serveraddr.sin_addr.s_addr = htonl( 0x7f000001 );
for ( int i = 0; i < 4; i++ ) {
if (sendto( fd, "hello", 5, 0, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0 ) {
perror( "sendto failed" );
break;
}
printf( "message sent\n" );
}
close( fd );
}
On the server side, keeping things simple means
Bind to INADDR_ANY, i.e. let the OS pick an appropriate interface.
Bind to a hard-coded port, e.g. 50037 (must be the same port the client uses).
Don't request the address information from recvfrom, i.e. pass NULL, 0 as the last two parameters.
With that in mind, here's what the server software looks like
int main( void )
{
int fd;
if ( (fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
perror( "socket failed" );
return 1;
}
struct sockaddr_in serveraddr;
memset( &serveraddr, 0, sizeof(serveraddr) );
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons( 50037 );
serveraddr.sin_addr.s_addr = htonl( INADDR_ANY );
if ( bind(fd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0 ) {
perror( "bind failed" );
return 1;
}
char buffer[200];
for ( int i = 0; i < 4; i++ ) {
int length = recvfrom( fd, buffer, sizeof(buffer) - 1, 0, NULL, 0 );
if ( length < 0 ) {
perror( "recvfrom failed" );
break;
}
buffer[length] = '\0';
printf( "%d bytes: '%s'\n", length, buffer );
}
close( fd );
}
I'm using C to implement a simple client-server retrieval system with Linux socket. I've now successfully connect the remote server, but when I close the connection, the server went down, i.e. the server program stopped.
What should I do avoid this?
here's sample of my code:
server:
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netinet/in.h>
int main(void)
{
int optval;
socklen_t optlen = sizeof(optval);
char str[100] = "";
int listen_fd, conn_fd;
struct sockaddr_in servaddr;
listen_fd = socket(AF_INET, SOCK_STREAM, 0);
// check if on
getsockopt(listen_fd, SOL_SOCKET, SO_KEEPALIVE, &optval, &optlen);
printf("keep alive is %s\n", (optval? "ON" : "OFF"));
// set it on
optval = 1;
optlen = sizeof(optval);
setsockopt(listen_fd, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen);
printf("done, check again.\n");
printf("keep alive is %s\n", (optval? "ON" : "OFF"));
bzero( &servaddr, sizeof(servaddr));
// set appropriate protocol and port number (15792)
// the htons() function converts the unsigned short integer
// from host byte order to network byte order.
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htons(INADDR_ANY);
servaddr.sin_port = htons(15792);
// Bind a name to a socket
bind(listen_fd, (struct sockaddr *) &servaddr, sizeof(servaddr));
// listening for incoming connection
listen(listen_fd, 10);
// accept a connection on a socket
conn_fd = accept(listen_fd, (struct sockaddr*) NULL, NULL);
do
{
// set str to null
bzero(str, 100);
// Read from a file descriptor (linux all)
read(conn_fd,str,100);
// print the received message
// printf("Received: %s\n",str);
if (!strcmp(str, "GET TIME\n"))
{
bzero(str, 100);
time_t clocks;
clocks = time(NULL);
sprintf(str, "%s", ctime(&clocks));
write(conn_fd, str, strlen(str));
//close(conn_fd);
}
else
{
bzero(str, 100);
strcpy(str, "ERROR: No such command.\n");
write(conn_fd, str, strlen(str));
//close(conn_fd);
}
} while (1);
}
client:
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc,char **argv)
{
// declare necessary variables
int sockfd;
char recv[1024] = "";
char command[100] = "";
struct sockaddr_in servaddr;
if (argc != 2)
{
printf("usage: %s <ip address>\n", argv[0]);
exit(EXIT_FAILURE);
}
// create a socket with the appropriate protocol
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("ERROR: Failed create cosket.\n");
exit(EXIT_FAILURE);
}
// Set all the socket structures with null values.
bzero(&servaddr, sizeof servaddr);
// set appropriate protocol and port number (1999)
// The htons() function converts the unsigned short integer
// hostshort from host byte order to network byte order.
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(15792);
// Convert IPv4 and IPv6 addresses from text to binary form
if (inet_pton(AF_INET, argv[1], &(servaddr.sin_addr)) <= 0)
{
printf("ERROR: Wrong ip address.\n");
exit(EXIT_FAILURE);
}
// attempt to connect to a socket
if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
{
printf("ERROR: Failed at connect.\n");
exit(EXIT_FAILURE);
}
else
{
printf("------ connect successfull ------\n");
}
do
{
printf("> ");
fgets(command, 100, stdin);
write(sockfd, command, strlen(command));
if (!strcmp(command, "QUIT\n"))
{
close(sockfd);
break;
}
// print the receive stuff
read(sockfd, recv, sizeof(recv));
fputs(recv, stdout);
bzero(recv, 1024);
} while (1);
}
In your server code, the accept() function must be called in the do-while loop:
// listening for incoming connection
listen(listen_fd, 10);
do
{
// accept a connection on a socket
conn_fd = accept(listen_fd, (struct sockaddr*) NULL, NULL);
...
close(conn_fd);
} while(1);
my question here is, why server ended if I close the connection from
the client.
Because then the blocking read call will return the value 0 indicating the connection was closed, which you promptly ignore. You then try (and fail) to compare the received data (which you have none) to the string and you will attempt to write the error message to the (now disconnected) client which will raise the SIGPIPE error which terminates your application.
– Some programmer dude