I had used Windows for socket programming recently, but my assignment requires students to use Linux Socket header(sys/socket.h) rather than Windows one.
So I'm starting from ground zero but the program freezes even though it is a very simple program that does nothing but only prints a message when a connection is made.
Server.cpp
#include <sys/socket.h>
#include <cstdio>
#include <stdlib.h>
#include <cstring>
#include <errno.h>
#include <string>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#define PORT 3490
#define BACKLOG 10
int main(void){
int sockfd, new_fd;
struct sockaddr_in my_addr;
struct sockaddr_in their_addr;
socklen_t sin_size;
if((sockfd = socket(PF_INET, SOCK_STREAM, 0))==-1){
perror("Socket creation failed");
exit(1);
}
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(PORT);
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(sockfd, (struct sockaddr*)&my_addr, sizeof(struct sockaddr))==-1){
perror("Socket binding failed");
exit(1);
}
if(listen(sockfd, BACKLOG) == -1){
perror("Socket listening failed");
exit(1);
}
sin_size = (socklen_t)sizeof(struct sockaddr_in);
while(true){
printf("Loop Test"); // This is not displayed at all
if((new_fd = accept(sockfd, (struct sockaddr*)&their_addr, &sin_size))==-1){
perror("Connetion accepting failed");
exit(1);
}
printf("Server got connection from %s\n", inet_ntoa(their_addr.sin_addr));
}
return 0;
}
Client.cpp
#include <sys/socket.h>
#include <cstdio>
#include <stdlib.h>
#include <cstring>
#include <errno.h>
#include <string>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#define PORT 3490
int main(void){
int sockfd;
struct sockaddr_in their_addr;
if((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1){
perror("Socket generating failed");
exit(1);
}
their_addr.sin_family = AF_INET;
their_addr.sin_port = htons(PORT);
their_addr.sin_addr.s_addr = INADDR_LOOPBACK;
if(connect(sockfd, (struct sockaddr*)&their_addr, sizeof(struct sockaddr)) == -1){
perror("Connection failed");
exit(1);
}
printf("Loop test"); // This is not displayed no matter if server is on or not
return 0;
}
As I mentioned in the code, it just stops and both perror and printf(for debugging) are not displayed.
Why is this happened? (I'm using Ubuntu)
There are two issues with your program. The first one is relatively minor, it is that you do not end your printf statements with "\n". Because of that the output is buffered and you do not see it immediately.
However, this would alone would not be visible (although it does make debugging harder as you are unsure what is happening) if you would not have a simple yet annoying bug - you fail to convert INADDR_LOOPBACK to big endian with htonl. Ironically, you do this for INADDR_ANY (which although good style is not doing anything real, since 0 is always 0), but do not do it where it really matters.
Related
I'm trying to complete a simple echo server. The goal is to repeat back the message to the client. The server and client both compile.The server is binded to localhost and port 8080. The client has the address, the port, and the message. When the client goes through the program to the sendto section, it stop and waits there. My goal it to have it sent to the server, and the server to send it back.
Problem: The client is send the message and the server is receiving it correctly but the server is not able to return the message. Please help!
SERVER SIDE CODE:
#include <iostream>
#include <string.h>
#include <fstream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define PORT 8080
using namespace std;
int main() {
int serSockDes, len, readStatus;
struct sockaddr_in serAddr, cliAddr;
char buff[1024] = {0};
char msg[] = "Hello to you too!!!\n";
//creating a new server socket
if((serSockDes = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("socket creation error...\n");
exit(-1);
}
//binding the port to ip and port
serAddr.sin_family = AF_INET;
serAddr.sin_port = htons(PORT);
serAddr.sin_addr.s_addr = INADDR_ANY;
if((bind(serSockDes, (struct sockaddr*)&serAddr, sizeof(serAddr))) < 0) {
perror("binding error...\n");
exit(-1);
}
readStatus = recvfrom(serSockDes, buff, 1024, 0, (struct sockaddr*)&cliAddr, (socklen_t*)&len);
buff[readStatus] = '\0';
cout<<buff;
cout<<len;
sendto(serSockDes, msg, strlen(msg), 0, (struct sockaddr*)&cliAddr, len);
return 0;
}
CLIENT SIDE CODE:
#include <iostream>
#include <fstream>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define PORT 8080
using namespace std;
int main(int argc, char** argv) {
int cliSockDes, readStatus, len;
struct sockaddr_in serAddr;
char msg[] = "Hello!!!\n";
char buff[1024] = {0};
//create a socket
if((cliSockDes = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("socket creation error...\n");
exit(-1);
}
//server socket address
serAddr.sin_family = AF_INET;
serAddr.sin_port = htons(PORT);
serAddr.sin_addr.s_addr = INADDR_ANY;
sendto(cliSockDes, msg, strlen(msg), 0, (struct sockaddr*)&serAddr, sizeof(serAddr));
readStatus = recvfrom(cliSockDes, buff, 1024, 0, (struct sockaddr*)&serAddr, (socklen_t*)&len);
buff[readStatus] = '\0';
cout<<buff;
return 0;
}
The client is trying to send its message to INADDR_ANY, which is wrong. It needs to send to a specific IP address instead. The server can listen to all of its local IP addresses using INADDR_ANY, that is fine, but the IP address that the client sends to must be one that the server listens on (or, if the client and server are on different network segments, the client must send to an IP that reaches the server's router, which then must forward the message to an IP that the server is listening on).
Also, your calls to recvfrom() and sendto() on both ends are lacking adequate error handling. In particular, the addrlen parameter of recvfrom() specifies the max size of the sockaddr buffer upon input, and upon output returns the actual size of the peer address stored in the sockaddr. But you are not initializing the len variable that you pass in as the addrlen, so recvfrom() is likely to fail with an error that you do not handle.
Try something more like this instead:
Server:
#include <iostream>
#include <string.h>
#include <fstream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
using namespace std;
#define PORT 8080
int main() {
int serSockDes, readStatus;
struct sockaddr_in serAddr, cliAddr;
socklen_t cliAddrLen;
char buff[1024] = {0};
char msg[] = "Hello to you too!!!\n";
//creating a new server socket
if ((serSockDes = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("socket creation error...\n");
exit(-1);
}
//binding the port to ip and port
serAddr.sin_family = AF_INET;
serAddr.sin_port = htons(PORT);
serAddr.sin_addr.s_addr = INADDR_ANY;
if ((bind(serSockDes, (struct sockaddr*)&serAddr, sizeof(serAddr))) < 0) {
perror("binding error...\n");
close(serSockDes);
exit(-1);
}
cliAddrLen = sizeof(cliAddr);
readStatus = recvfrom(serSockDes, buff, 1024, 0, (struct sockaddr*)&cliAddr, &cliAddrLen);
if (readStatus < 0) {
perror("reading error...\n");
close(serSockDes);
exit(-1);
}
cout.write(buff, readStatus);
cout << endl;
if (sendto(serSockDes, msg, strlen(msg), 0, (struct sockaddr*)&cliAddr, cliAddrLen)) < 0) {
perror("sending error...\n");
close(serSockDes);
exit(-1);
}
close(serSockDes);
return 0;
}
Client:
#include <iostream>
#include <fstream>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
using namespace std;
#define PORT 8080
int main(int argc, char** argv) {
int cliSockDes, readStatus;
struct sockaddr_in serAddr;
socklen_t serAddrLen;
char msg[] = "Hello!!!\n";
char buff[1024] = {0};
//create a socket
if ((cliSockDes = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("socket creation error...\n");
exit(-1);
}
//server socket address
serAddr.sin_family = AF_INET;
serAddr.sin_port = htons(PORT);
serAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
if (sendto(cliSockDes, msg, strlen(msg), 0, (struct sockaddr*)&serAddr, sizeof(serAddr)) < 0) {
perror("sending error...\n");
close(cliSockDes);
exit(-1);
}
serAddrLen = sizeof(serAddr);
readStatus = recvfrom(cliSockDes, buff, 1024, 0, (struct sockaddr*)&serAddr, &serAddrLen);
if (readStatus < 0) {
perror("reading error...\n");
close(cliSockDes);
exit(-1);
}
cout.write(buff, readStatus);
cout << endl;
close(cliSockDes);
return 0;
}
Here I am checking UDP connection of IP address with specific port by using attached code. In my code if I give any IP and any port number it is getting connected successfully, the max range of port number is 5 digit but if I give more than 5 digit it will still get connection.
Major thing is on giving failure cases to check UDP Connection it passed that cases also.
failure cases i choosed:
1)not reachable IP
2)giving any port number
please help me to figure out what mistake i did in my code and what i can do in my code to check UDP connection is available for IP with specific port.My code attached below.
Thanks in Advance
#include <cstdlib>
#include <stdio.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <iostream>
#include <string>
#include <string.h>
#include <unistd.h>
using namespace std;
int main()
{
int sockfd,rv;
struct addrinfo *servinfo, *p,hints;
struct sockaddr_in *h;
string host ="172.30.36.150";
int port=8997345;
memset(&hints, 0, sizeof hints);
struct sockaddr_in clientService;
int serversockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (serversockfd == -1) {
fprintf(stderr, "Error in socket %d\n", errno);
}
clientService.sin_family = AF_INET;
rv = getaddrinfo( host.c_str() , NULL , &hints , &servinfo);
string strhost = "";
if(rv ==0){
p = servinfo;
h = (struct sockaddr_in *) p->ai_addr;
char chost[INET_ADDRSTRLEN];
strcpy(chost , inet_ntoa( h->sin_addr ) );
strhost.append(chost);
freeaddrinfo(servinfo);
}
clientService.sin_addr.s_addr = inet_addr(strhost.c_str());
clientService.sin_port = htons((u_short)port);
int res = connect(serversockfd, (struct sockaddr*) &clientService,
sizeof(clientService));
close(serversockfd);
if (res == -1) {
fprintf(stderr, "Error connecting socket %d\n", errno);
}else{
cout<<"successfully connected"<<endl;
}
}
I am trying to make a C++ server-client communication program. Currently, both server and client are on localhost.
When I run server.cpp, it waits at "Listening...", as expected, and does not continue further till I don't run client.cpp. When client is run, server prints "Connected" and both server and client end.
But when I run client.cpp only, it prints "Connecting..." and then "Connected" after one second, even if server.cpp is not running, and specified port is not open.
I have triple checked both codes, tried them many times, also checked open ports before running only client, changed port many times, but nothing worked. Why does client say "Connected" even when server is not running?
server.cpp:
#include <cstdio>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <arpa/inet.h>
#define PORT 11056
int main(int argc, char** argv) {
int sock = socket(AF_INET, SOCK_STREAM, PF_UNSPEC);
if (sock == -1) {
printf("E) Socket creation\n");
return 1;
}
struct sockaddr_in server, client;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = PORT;
server.sin_family = AF_INET;
int binded = bind(sock, (struct sockaddr *)&server, sizeof(server));
if (binded == -1) {
printf("E) Binding\n");
return 1;
}
printf("4) Listening...\n");
listen(sock, 5);
int new_sock = accept(sock, (struct sockaddr *)&client, (socklen_t *)sizeof(client));
printf("5) Connected\n");
shutdown(sock, SHUT_RDWR);
close(new_sock);
close(sock);
printf("EXIT\n");
return 0;
}
client.cpp
#include <cstdio>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#define PORT 11056
int main(int argc, char** argv) {
int sock = socket(AF_INET, SOCK_STREAM, PF_UNSPEC);
if(sock == -1) {
printf("Error creating socket\n");
return 1;
}
struct sockaddr_in client;
client.sin_port = PORT;
client.sin_family = AF_INET;
client.sin_addr.s_addr = inet_addr("127.0.0.1");
printf("3) Connecting...\n");
connect(sock, (struct sockaddr *)&client, sizeof(client));
printf("4) Connected\n");
close(sock);
printf("EXIT");
return 0;
}
When I run the code it doesn't seem to run the entire main function when this line
connect_sock = accept(sock, (struct sockaddr *)&serv_name, &len);
is in it. It won't even print the first cout at the beginning, but when I comment it out it works fine,can someone tell me the reason for this?
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <iostream>
#define PORT 1227
#define SIM_LENGTH 10;
using namespace std;
void clean_up(int cond, int *sock){
cout<<"exiting";
close(*sock);
exit(cond);
}
int main(void){
cout<<"working;
int sock;
int connect_sock;
struct sockaddr_in serv_name;
size_t len;
int count;
sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock<0){
cout<<"Error connecting to socket";
clean_up(1, &sock);
}
bzero(&serv_name, sizeof(serv_name)); // set name as physical address
serv_name.sin_family = AF_INET;
serv_name.sin_port = htons(PORT);
if(bind(sock,(struct sockaddr *)&serv_name, sizeof(serv_name))<0){
cout<<"error naming channel";
clean_up(1, &sock);
}
cout<<"waiting for connection from client";
listen(sock, 1);
len = sizeof(serv_name);
connect_sock = accept(sock, (struct sockaddr *)&serv_name, &len);
cout<<connect_sock;
cout<<"server wrote";
close(connect_sock);
cout<<"connect?";
}
It's waiting for a connection. It doesn't print the first cout because you didn't ask it to. Try:
cout<<"waiting for connection from client"<<endl;
I type two program one for client and one for server.
server is tcp concurrent echo server with select call,in order to use only one process to all client.
it uses apparent concurrency.
I develop program and run its working but after 3/4 message exchange bet client and server.
buffer content at server changes it showing current message with some character from the previous message.
I am not getting why this is happening.
Please anyone able to help me...
//Client Program
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <arpa/inet.h>
#include <iostream>
using namespace std;
#define MAXLINE 4096 /*max text line length*/
#define serv_PORT 3000 /*port*/
int main(int argc,char **argv)
{
int sockfd;
struct sockaddr_in servaddr;
char sendline[MAXLINE];
char recvline[MAXLINE];
/*int sendchars,recvchar;
char buf[MAXLINE];
*/
if (argc !=2)
{
cerr<<"Usage: Femto: <IP address of the serv"<<endl;
exit(1);
}
//Create a socket for the client
if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) <0)
{
cerr<<"Problem in creating the socket"<<endl;
exit(1);
}
//Creation of the socket
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr= inet_addr(argv[1]);
servaddr.sin_port = htons(serv_PORT);
//Connection of the client to the socket
if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr))<0)
{
cerr<<"Problem in connecting to the serv"<<endl;
exit(1);
}
while (fgets(sendline, MAXLINE, stdin) != NULL)
{
send(sockfd, sendline, strlen(sendline), 0);
if (recv(sockfd, recvline, MAXLINE,0) == 0)
{
cerr<<"The serv terminated"<<endl;
exit(1);
}
cout<< "String received from the serv: ";
fputs(recvline, stdout);
}
exit(0);
}
//Server program
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <iostream>
#include <sys/select.h>
#include <sys/time.h>
using namespace std;
#define MAXLINE 4096 /*max text line length*/
#define serv_PORT 3000 /*port*/
#define LISTENQ 65535
int main (int argc, char **argv)
{
int msock,ssock;
fd_set rfds;
fd_set afds;
int fd,nfds;
socklen_t client_len ;
char buf[MAXLINE];
struct sockaddr_in clientaddr, servaddr;
if ((msock = socket (AF_INET, SOCK_STREAM, 0)) <0)
{
cerr<<"Problem in creating the socket"<<endl;
exit(1);
}
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(serv_PORT);
bind (msock, (struct sockaddr *) &servaddr, sizeof(servaddr));
listen (msock, LISTENQ);
nfds=getdtablesize();
FD_ZERO(&afds);
FD_SET(msock,&afds);
while(1)
{
memcpy(&rfds,&afds,sizeof(rfds));
if(select(nfds,&rfds,(fd_set *)0,(fd_set *)0,(struct timeval * )0)<0)
{
cerr<<"Error in select";
// exit(1);
}
if(FD_ISSET(msock,&rfds))
{
//int ssock;
ssock= accept(msock,(struct sockaddr *)&clientaddr,&client_len);
if(ssock<0)
{
cerr<<"Accept error";
}
FD_SET(ssock,&afds);
}
int n;
for(fd=0;fd<nfds;++fd)
if(fd!=msock && FD_ISSET (fd,&rfds))
while ( (n = recv(fd, buf, MAXLINE,0)) > 0) {
cout<<"String received from and resent to the client:"<<endl;
puts(buf);
send(fd, buf, n, 0);
}
close(fd);
FD_CLR(fd,&afds);
}
}
output::
client-hi
server-hi
client-bye
server-bye
//after some message exchange
client-wru?
server-wru?
client- i m here
server-i am here u?
You're making the usual mistake of ignoring the count returned by recv(). The data in the buffer is only valid up to that count. The rest of it is unchanged from its previous value.
You're also ignoring the possibility of an error in bind(), listen(), send(), and recv().