I've got a small program with a client and server. The server starts, connects to the client and receives a host and second port number from the client, then sends some information back to the client about it's directory. The function in the server that sends data back works something like this:
void sendStuff(char *host, char *port) {
int sockfd, numbytes;
struct addrinfo hints, *servinfo;
struct sockaddr_storage client_info;
socklen_t addr_size;
size_t i = 0;
int rv;
// clear hints
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
memset(&servinfo, 0, sizeof(servinfo));
if ((rv = getaddrinfo(host, port, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
}
// create socket
sockfd = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol);
if (sockfd == -1) {
perror("There was an error creating your socket.");
close(sockfd);
exit(1);
}
// connect using socket
int conn;
conn = connect(sockfd, servinfo->ai_addr, servinfo->ai_addrlen);
if(conn == -1) {
perror("Error connecting to server.");
close(sockfd);
exit(1);
}
send(sockfd, "hey!", strlen("hey!"), 0);
}
Currently testing over localhost, which is being printed as 16.2.197.67 on the client. That doesn't seem like a localhost IP, so I suppose I could be screwing up the host somehow. Connecting to the waiting socket over telnet works, but not through this function.
Related
Basically my server/client socket functions work perfectly fine using the loopback address, or even my eth0 address on my laptop. Howver, once I move my code into the test environment it will be used in, I get connection time outs, or connection refused depending on the changes I have tried to make.
As of now the code I am about to post results in a Connection time out.
CLIENT
void buildConnection(int* txmt_sock, Connection conn_info)
{
struct sockaddr_in servinfo; /* server address */
servinfo.sin_family = AF_INET;
servinfo.sin_addr.s_addr = INADDR_ANY;
servinfo.sin_port = htons(conn_info.port);
if(inet_aton(conn_info.ip, &servinfo.sin_addr) < 1)
{
fprintf(stderr, "Read error: %s\n", strerror(errno));
abort();
}
/*int socket(int domain, int type, int protocol)*/
if ((*txmt_sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("client: socket");
abort();
}
/*int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);*/
if (connect(*txmt_sock,(struct sockaddr *)&servinfo,(socklen_t)sizeof(servinfo)) == -1)
{
close(*txmt_sock);
perror("client: connect");
abort();
}
printf("Successfully connected on port %s:%d\n", conn_info.ip, conn_info.port);
}
SERVER
void returnConnection(Connection* conn_info)
{
int status, ext_conn, yes = 1;
char portStr[5];
struct addrinfo hints, *servinfo;
struct sockaddr_storage ext_addr;
socklen_t addr_size;
struct sockaddr *restrict;
/* Formats PORT for use with getaddrinfo(), can't cast #define*/
snprintf(portStr, 6, "%d", conn_info->port);
memset(&hints, 0, sizeof(hints)); /*make sure the struct is empty*/
hints.ai_family = AF_UNSPEC; /*don't care IPv4 or IPv6*/
hints.ai_socktype = SOCK_STREAM; /*TCP stream sockets*/
hints.ai_flags = AI_PASSIVE; /*fill in my IP for me*/
if ((status = getaddrinfo(NULL, portStr, &hints, &servinfo)) != 0)
{
fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
exit(1);
}
if((conn_info->listen_sock = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol)) == -1)
{
fprintf(stderr, "Socket error: %s\n", strerror(errno));
exit(1);
}
if(setsockopt(conn_info->listen_sock,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1)
{
perror("setsockopt");
exit(1);
}
if(bind(conn_info->listen_sock, servinfo->ai_addr, servinfo->ai_addrlen) == -1)
{
fprintf(stderr, "Bind error: %s\n", strerror(errno));
exit(1);
}
freeaddrinfo(servinfo);
if(listen(conn_info->listen_sock, 1) == 1)
{
fprintf(stderr, "Listening error: %s\n", strerror(errno));
exit(1);
}
addr_size = sizeof(ext_conn);
if((ext_conn = accept(conn_info->listen_sock, (struct sockaddr *)&ext_addr, &addr_size)) == -1)
{
fprintf(stderr, "Accept error: %s\n", strerror(errno));
exit(1);
};
conn_info->receiving_sock = ext_conn;
}
This is a multi-threaded program that collects image data from 8 different ports/threads. I use my Connection struct to store all the pertinent data for each thread. Each thread has it's own Connection.
typedef struct connection{
char* file;
int port;
char* ip;
pthread_t *thread;
}Connection;
Connection->ip is not used in the server side, but is uses on the Client side. The server side of the code resides on a multi-cpu, multi-nic IBM server. I am not certain if I need to manually assign the IP or not because of that. I am assuming the OS and network cards manage on their own using the incoming PORT numbers from the clients, and the individual PORT numbers that my Server threads listen on. But all I know is that it works on my laptop to itself.
It's a completely new vanilla install on this machine with openSuse, so I don't think any of the ports I am using, 5050-5053 and 5055-5058, are turned off or anything like that.
I created a server socket in C. This is the most basic stuff like what you would fine in a simple TCP server example. Server code is below. I also created a client socket that runs on the host machine. Code also below. However, for some reason the client is not able to connect to the server. The IP address I used is the same as the one under the entry eth0 from the "ip addr" command. The network adapter of the VM is a bridged connection.
The exact same code works when both client and server run on the same machine (the host).
Thank you!
Server code:
int sockfd;
int clientfd;
struct sockaddr_in self;
struct sockaddr_in client_addr;
int addrlen = sizeof (client_addr);
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("Socket");
return EXIT_FAILURE;
}
printf("Socket descriptor is: %d\n", sockfd);
memset(&self, 0, sizeof (self));
self.sin_family = AF_INET;
self.sin_port = htons(MY_PORT);
self.sin_addr.s_addr = INADDR_ANY;
if (bind(sockfd, (struct sockaddr*) &self, sizeof (self)) != 0) {
perror("socket--bind");
return EXIT_FAILURE;
}
if (listen(sockfd, 20) != 0) {
perror("socket--listen");
return EXIT_FAILURE;
}
clientfd = accept(sockfd, (struct sockaddr*) &client_addr, &addrlen);
printf("%s:%d connected\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
Client Code:
int sock;
struct sockaddr_in server;
//struct sockaddr_in client;
struct hostent *hp;
//char buf[BUFFER_SIZE];
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
die(6, "Opening stream socket");
printf("Client socket file descriptor is: %d\n", sock);
memset(&server, (char) 0, sizeof (server));
server.sin_family = AF_INET;
hp = gethostbyname(host_name);
if (!hp) {
//sprintf(buf, "%s: unknown host\n", host_name);
die(8, "%s: unknown host\n", host_name);
}
memcpy(hp->h_addr, &server.sin_addr, hp->h_length);
server.sin_port = htons((u_short) SERVER_PORT);
/* Try to connect */
if ((connect(sock, (struct sockaddr *) &server, sizeof (server))) < 0)
die(7, "%s", "Failed to connect stream socket\n");
I'm working on a C program that creates a connection between a client and server. When I run connect on the socket I've already created I keep getting an error that I'm passing an invalid argument.
Any help would be awesome!
void client(char* ipAddress, char* serverPort){
//code for setting up the IP address and socket information from Beej's Guide to Network Programming
//Need to setup two addrinfo structs. One for the client and one for the server that the connection will be going to
int status;
//client addrinfo
struct addrinfo hints, *res; // will point to the results
//server addrinfo
int socketDescriptor;
int addressLength;
memset(&hints, 0, sizeof hints); // make sure the struct is empty
hints.ai_family = AF_UNSPEC; // don't care IPv4 or IPv6
hints.ai_socktype = SOCK_STREAM; // TCP stream sockets
hints.ai_flags = AI_PASSIVE; // fill in my IP for me
//setup client socket
if ((status = getaddrinfo(ipAddress, serverPort, &hints, &res)) != 0) {
printf("%s \n", "This error above");
fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
exit(1);
}
if((socketDescriptor = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) ==-1){
perror("client: socket");
}
addressLength = sizeof hints;
if(connect(socketDescriptor, res->ai_addr, addressLength)==-1){
close(socketDescriptor);
perror("client: connect");
}
}
Apart from some inconsistent variable names in your code,
this seems to be wrong:
addressLength = sizeof hints;
if(connect(socketDescriptor, res->ai_addr, addressLength)==-1) ...
It should be
if(connect(socketDescriptor, res->ai_addr, res->ai_addrlen)==-1) ...
I am writing a small socket program in C. In server side I create a socket descriptor using socket() system call, then I am binding that socket with a port. After this I am trying to get the IP/Port no of the descriptor, it gives port no different then the bind port no. I am trying to get back IP/Port using getsockname() method, Is it right to use this method ? Please help me.
#define SERVER_ADDR "127.0.0.1"
#define SERVER_PORT "9090" // actual port no I am binding
#define QUEUE_LENGTH 10
int main()
{
struct addrinfo hints, *servinfo, *temp;
memset(&hints,0,sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
// here I am passing SERVER_PORT == 9090
int status = getaddrinfo(SERVER_ADDR,SERVER_PORT,&hints,&servinfo);
if(status != 0)
{
printf("Server: getaddrinfo() errored with code %d\n",status);
return;
}
int sfd = -1;
for(temp = servinfo; temp != NULL; temp = servinfo->ai_next)
{
sfd = socket(temp->ai_family,temp->ai_socktype,temp->ai_protocol);
if(sfd == -1)
{
printf("Server: Socket error with code %d\n",sfd);
continue;
}
status = bind(sfd,temp->ai_addr,temp->ai_addrlen);
if(status == -1)
{
printf("Server: Bind error with code %d\n",status);
continue;
}
printf("Server: Bind Successful\n");
// un necessary code goes here
struct sockaddr_in server_address;
char ipv4[INET_ADDRSTRLEN];
int addr_size = sizeof(server_address);
// i am using below method to get the port no from socket descriptor
getsockname(sfd, (struct sockaddr *)&server_address, &addr_size);
// I am expecting below will print 9090. but it prints different port no why ?
printf("Server Port: %d\n",server_address.sin_port);
printf("Port from getsddrinfo: %d\n",( (struct sockaddr_in *)temp->ai_addr)->sin_port);
inet_ntop(AF_INET, &(server_address.sin_addr),ipv4,INET_ADDRSTRLEN);
printf("Server IP Address: %s\n",ipv4);
// un necessary code ends here
break;
}
if(temp == NULL)
{
printf("Server: Failed to bind\n");
return;
}
status = listen(sfd,QUEUE_LENGTH);
if(status == -1)
{
printf("Server: Listening failed\n");
return;
}
printf("Server: waiting for coneections...\n");
while(1)
{
printf("Server: Main loop, will wait for client to connect...\n");
struct sockaddr client_address;
int addr_length = sizeof client_address;
// accepting client
int new_sfd = accept(sfd,&client_address,&addr_length);
}
printf("Server: Done!\n");
}
Output is:
Server: Bind Successful
Server Port: 33315 --> why this different from one I have binded (9090)
Port from getsddrinfo: 33315 --> why this different from one I have binded (9090)
Server IP Address: 127.0.0.1
Server: waiting for coneections...
Server: Main loop, will wait for client to connect...
The decimal members of struct sockaddr are returned in network byte order.
So you need to convert such values to host byte order, using the ntoh family of functions before using them, printing them.
add hints.sin_port = htons( 9090 );after hints.ai_socktype = SOCK_STREAM;
I am trying to send a string HI to a server over UDP in a particular port and then to receive a response. However, after I try to get the response using recvfrom() I was stuck in blocking state. I tried using connected UDP but I got:
Error receiving in UDP: Connection refused
What could be the reasons for this? The server is not under my control, but I do know its working fine.
I have added the code
int sockfdudp;
char bufudp[MAXDATASIZE], port[6];
struct addrinfo hints, *servinfo, *p;
struct sockaddr_storage addr;
int rv;
char s[INET6_ADDRSTRLEN];
int bytes_recv, bytes_sent;
socklen_t len;
scanf("%s",port);
printf("UDP Port: %s \n", port);
// Start connecting to datagram server
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
if ((rv = getaddrinfo(SERVER_NAME, port, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
return 1;
}
// loop through all the results and make a socket
for(p = servinfo; p != NULL; p = p->ai_next) {
if ((sockfdudp = socket(p->ai_family, p->ai_socktype,
p->ai_protocol)) == -1) {
perror("Creating datagram socket");
continue;
}
if (connect(sockfdudp, p->ai_addr, p->ai_addrlen) == -1) {
close(sockfdudp);
perror("Connecting stream socket");
continue;
}
break;
}
if (p == NULL) {
fprintf(stderr, "ClientUDP: failed to bind socket\n");
return 2;
}
freeaddrinfo(servinfo);
if ((bytes_sent = sendto(sockfdudp, UDP_MSG, strlen(UDP_MSG), 0, p->ai_addr, p->ai_addrlen)) == -1) {
perror("ClientUDP: Error sending data");
exit(1);
}
printf("Data %s sent\n", UDP_MSG );
len = sizeof(struct sockaddr_storage);
if ((bytes_recv = recvfrom(sockfdudp, bufudp, MAXDATASIZE-1, 0,(struct sockaddr*)&addr, &len)) == -1) {
perror("Error receiving in UDP");
exit(1);
}
printf("Bytes recv %d\n", bytes_recv);
bufudp[bytes_recv] = '\0';
printf("ClientUDP: Received\n %s \n",bufudp );
close(sockfdudp);
return 0;
Chances are your're sending something to a server who does not listen on that particular port.
That would cause an icmp message to be sent back , and your next recvfrom will return an error in the case where you connect the socket.
Check with tcpdump or wireshark what's going on on the wire.
My guess would be that your ip address is bad somehow, or the port is already in use somehow. UDP is connectionless, so there really isn't any "connection" to fail.