I'm trying to write a simple code for a server to print something from a function
This code gives me an error :
request for member ‘sin_addr’ in something not a structure or union
and I don't understand why
can you help me?
#include <sys/types.h>
#include <netinet/in.h>
#include <inttypes.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <strings.h>
#include <unistd.h>
#include <stdio.h>
void printsin(struct sockaddr_in *s, char *str1, char *str2) {
printf("%s\n", str1);
printf("%s: ", str2);
printf("%d = ,", s.sin_addr.s_addr);
printf(" %d = ", s.sin_port);
printf("\n");
}
int main(int argc, char *argv[])
{
int socket_fd, cc, fsize;
struct sockaddr_in s_in, from;
struct { char head; u_long body; char tail;} msg;
socket_fd = socket (AF_INET, SOCK_DGRAM, 0);
bzero((char *) &s_in, sizeof(s_in)); /* They say you must do this */
s_in.sin_family = (short)AF_INET;
s_in.sin_addr.s_addr = htonl(INADDR_ANY); /* WILDCARD */
s_in.sin_port = htons((u_short)0x3333);
printsin( &s_in, "RECV_UDP", "Local socket is:");
fflush(stdout);
bind(socket_fd, (struct sockaddr *)&s_in, sizeof(s_in));
for(;;) {
fsize = sizeof(from);
cc = recvfrom(socket_fd,&msg,sizeof(msg),0,(struct sockaddr *)&from,&fsize);
//printsin( &from, "recv_udp: ", "Packet from:");
printf("Got data ::%c%ld%c\n",msg.head,(long) ntohl(msg.body),msg.tail);
fflush(stdout);
}
return 0;
}
Thank you
printf("%d = ,", s->sin_addr.s_addr);
printf(" %d = ", s->sin_port);
That should fix it you pass it in as a pointer then you never deference it.
Related
I am writing a udp client-server program for MacOS on C-language. Found a realisation of UDP-protocol, and it works properly on Linux (checked by myself), but when I try to build it on Mac it returns a warning of undeclared variable MSG_CONFIRM, and when I try to Run it, the program doesn't get or send any message.
I've already tried to find a solution in Google but there is no any. What can I try next?
This is the "client"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdbool.h>
#include "utils.h"
#define BUF_SIZE 1024
int main(int argc, char ** argv) {
Args args = get_args(argc, argv);
int sock_fd;
struct sockaddr_in server_addr;
if ( (sock_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
throw(BAD_EXIT_STATUS, "Socket creation failed");
}
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(args.port);
server_addr.sin_addr.s_addr = inet_addr(args.IP);
while(1) {
char buffer[BUF_SIZE];
char *hello = readline(stdin);
int n;
socklen_t len;
sendto(sock_fd, (const char *) hello, strlen(hello), MSG_CONFIRM,
(const struct sockaddr *) &server_addr, sizeof(server_addr));
n = recvfrom(sock_fd, (char *) buffer, BUF_SIZE, MSG_WAITALL,
(struct sockaddr *) &server_addr, &len);
buffer[n] = '\0';
printf("[Server]: %s", buffer);
}
close(sock_fd);
return 0;
}
This is the "server"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdbool.h>
#include <math.h>
#include "utils.h"
#include "obrab.h"
#define BUF_SIZE 1024
#ifndef MSG_CONFIRM
#define MSG_CONFIRM 2048
#endif
int main(int argc, char** argv) {
Args args = get_args(argc, argv);
int sock_fd;
struct sockaddr_in server_addr, client_addr;
if ((sock_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
throw(BAD_EXIT_STATUS, "Socket creation failed");
}
memset(&server_addr, 0, sizeof(server_addr));
memset(&client_addr, 0, sizeof(client_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(args.port);
server_addr.sin_addr.s_addr = inet_addr(args.IP);
if (bind(sock_fd, (const struct sockaddr*) &server_addr, sizeof(server_addr)) < 0) {
throw(BAD_EXIT_STATUS, "Bind failed");
}
while(1) {
char buffer[BUF_SIZE];
int n;
socklen_t len;
n = recvfrom(sock_fd, (char*) buffer, BUF_SIZE,
MSG_WAITALL, (struct sockaddr*) &client_addr, &len);
buffer[n] = '\0';
if (fork() == 0) {
char *hello = buffer;
sendto(sock_fd, (const char *) hello, strlen(hello),
MSG_CONFIRM, (const struct sockaddr *) &client_addr, len);
} else {
printf("[Client]: %s", buffer);
}
}
}
I also created some header-files, there is a code below
"keys.h"
#ifndef keys_h
#define keys_h
// Struct for console arguments
unsigned short int prt;
char* L2ADDR;
char* L2LOGFILE;
unsigned short int L2WAIT;
typedef struct Args {
// unsigned short int (*L2PORT) (unsigned short int L2PORT); // -p
// char* (*L2WAIT) (char* L2ADDR); //-a
// char* (*L2LOGFILE) (char* L2LOGFILE); //-l
// unsigned short int (*L2WAIT) (unsigned short int L2WAIT); //-w
} Args;
char ip[] = "128.0.0.1";
unsigned a, b, c, d;
// reception and recognition of args
Args get_args(int argc, char **argv) {
Args args = {};
int opt;
char *opts = "palwvh";
while((opt = getopt(argc, argv, opts)) != -1) {
switch(opt) {
case 'p':
break;
case 'a':
if (sscanf(ip, "%d.%d.%d.%d", &a, &b, &c, &d) == 4 && a < 256) printf("YES\n");
else {
perror("NO\n");
exit(2);
}
break;
case 'l':
// currentParser = lblog;
break;
case 'w':
// currentParser = lbwait;
break;
case 'v':
printf("Version: 0.0.1 omega\n");
break;
case 'h':
printf("Use can use following keys: \n"
"\t-v -- prints out a version of the program;\n"
"\t-h -- output of the manual;\n"
"\t-w N -- Imitates job pausing serving process for N sec;\n"
"\t-d -- Set up program in daemon-mode;\n"
"\t-l /path/to/log -- set up a path to log-file;\n"
"\t-a ip -- Set up an adress in what server listens;\n"
"\t-p port -- Set up port, in what server listens.\n\n");
break;
default:
perror("Unknown key! Use -h key to read manual");
}
}
return args;
}
#endif /* keys_h */
"Utils.h"
#ifndef UTILS_H
#define UTILS_H
#define BAD_EXIT_STATUS 1
typedef struct Args {
int waitFor; // -w N
bool isDaemon; // -d
char* logFile; // -l path
char* IP; // -a IP
int port; // -p port
} Args;
Args get_args(int, char**);
void throw(int, char*);
char * readline(FILE*);
#endif
When you compile you need to write a command like this: ./server -a ip -p port (entered 127.0.0.1 and 8080) Then you need to run a client in another window with similar key parameters. In theory you write messages in client and then they are sent to server. But it doesn't send or get any message.
I am using the UDP auxiliary functions encapsulated below replacing the calls the functions of the sockets libraries to simulate and allow some testing on the UDP client and server. But I am not able to make the connection between them and pass the arguments correctly.
/********auxiliary functions for using UDP sockets*********/
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <strings.h>
#include "tp_socket.h"
#define MTU 1024
int tp_mtu(void)
{
fprintf(stderr,"tp_mtu called\n");
return MTU;
}
int tp_sendto(int so, char* buff, int buff_len, so_addr* to_addr)
{
int count;
fprintf(stderr,"tp_sendto called (%d bytes)\n", buff_len);
count = sendto(so, (void*)buff, buff_len, 0,
(struct sockaddr*) to_addr, sizeof(struct sockaddr_in));
fprintf(stderr,"tp_sendto returning (sent %d bytes)\n", count);
return count;
}
int tp_recvfrom(int so, char* buff, int buff_len, so_addr* from_addr)
{
int count;
unsigned int sockaddr_len = sizeof(struct sockaddr_in);
fprintf(stderr,"tp_recvfrom called (%d bytes)\n",buff_len);
count = recvfrom(so,(void*)buff,(size_t)buff_len,0,
(struct sockaddr*) from_addr, &sockaddr_len);
fprintf(stderr,"tp_recvfrom returning (received %d bytes)\n",count);
return count;
}
int tp_init(void)
{
fprintf(stderr,"tp_init called\n");
return 0;
}
int tp_socket(unsigned short port)
{
int so;
struct sockaddr_in local_addr;
int addr_len =sizeof(local_addr);
fprintf(stderr,"tp_socket called\n");
if ((so=socket(PF_INET,SOCK_DGRAM,0))<0) {
return -1;
}
if (tp_build_addr(&local_addr,INADDR_ANY,port)<0) {
return -2;
}
if (bind(so, (struct sockaddr*)&local_addr, sizeof(local_addr))<0) {
return -3;
}
return so;
}
int tp_build_addr(so_addr* addr, char* hostname, int port)
{
struct hostent* he;
fprintf(stderr,"tp_build_addr called\n");
addr->sin_family = PF_INET;
addr->sin_port = htons(port);
if (hostname==NULL) {
addr->sin_addr.s_addr = INADDR_ANY;
} else {
if ((he=gethostbyname(hostname))==NULL) {
return -1;
}
bcopy(he->h_addr,&(addr->sin_addr.s_addr),sizeof(in_addr_t));
}
return 0;
}
My code at the moment of the UDP client:
/********clientUDP*********/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include "tp_socket.h"
int main(int argc, char *argv[])
{
so_addr to_addr;
char *ip_server;
char my_buffer[10];
int port_servidor, tam_buffer;
if (argc != 5)
{
perror("Error");
exit(-1);
}
*ip_server = argv[1];
port_server = atoi(argv[2]);
char arquivo = argv[3];
tam_buffer = atoi(argv[4]);
tp_init();
tp_socket(port);
tp_build_addr(&to_addr, ip_server, port_server);
exit(0);
}
My code at the moment of the UDP server:
/********serverUDP*********/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include "tp_socket.h"
int main(int argc, char *argv[])
{
so_addr my_addr;
int aux, so, mtu, port_server,tam_buffer,n;
char *archive;
char buffer[10];
FILE *file;
if (argc != 3)
{
perror("Error");
exit(-1);
}
port_server = atoi(argv[1]);
tam_buffer = atoi(argv[2]);
aux = tp_init();
if (aux < 0)
{
perror("error");
exit(aux);
}
mtu = tp_mtu();
so = tp_socket(port_server);
tp_recvfrom(so, buffer, 10 , &my_addr);
n = read( so,tam_buffer,1);
file = fopen(archive,"r");
if ( file != NULL )
{
n=fread(buffer,1,atoi(argv[2]),file);
while ( n > 0)
{
write(so,buffer,n);
n=fread(buffer,1, atoi(argv[2]),file);
}
} else
{
printf("error\n");
exit(0);
}
fclose(file);
shutdown(so,2);
close();
return 0;
}
Could someone please explain how I use the auxiliary functions to connect the client to the server and transfer files? I've be I've been locked up a long time at this stage.
I have a simple program in C, which resolves IP addresses into hostnames.
#include <stdio.h> /* stderr, stdout */
#include <netinet/in.h> /* in_addr structure */
#include <strings.h>
#include <arpa/inet.h>
#include <netdb.h>
int main(int argc, char **argv) {
if ( argc == 2) {
struct sockaddr_in sa;
sa.sin_family = AF_INET;
inet_pton(AF_INET, argv[1], &sa.sin_addr);
char node[NI_MAXHOST];
int res = getnameinfo((struct sockaddr*)&sa, sizeof(sa), node, sizeof(node), NULL, 0, 0);
if (res)
{
printf("%s\n", gai_strerror(res));
return 1;
}
printf("%s\n", node);
return 0;
}
}
It works fine (i.e. ./a.out 10.1.1.2) but I need to modify it so that it accepts IP addresses in HEX format.
Is there some function to convert hex IP addresses to decimal?
I haven't tested this but should work.
#include <stdio.h> /* stderr, stdout */
#include <netinet/in.h> /* in_addr structure */
#include <strings.h>
#include <arpa/inet.h>
#include <netdb.h>
int main(int argc, char **argv) {
if ( argc == 2) {
struct sockaddr_in sa;
char a[2048] = {'\0'}; // placeholder not to overflow and initialised.
if( NULL == strchr(argv[1],'.') )
{
unsigned int unit0, uint1, uint2, uint3;
sscanf(argv[1], "%2x%2x%2x%2x", &uint0, &uint1, &uint2, &uint3);
sprintf(a,"%u.%u.%u.%u",uint0, uint1, uint2, uint3);
}
else
strcpy(a.argv[1]);
sa.sin_family = AF_INET;
inet_pton(AF_INET, a, &sa.sin_addr);
char node[NI_MAXHOST];
int res = getnameinfo((struct sockaddr*)&sa, sizeof(sa), node, sizeof(node), NULL, 0, 0);
if (res)
{
printf("%s\n", gai_strerror(res));
return 1;
}
printf("%s\n", node);
return 0;
}
}
Thanks
I wanted to get the IP address and the subnet mask. Now the IP part is done, however I couldn't find any socket function that would return a structure with the subnet mask in it.
Does a socket function exist, that returns it in a structure?
Thanks!
In Unix using getifaddrs
struct ifaddrs haves a member named ifa_netmask (Netmask of interface)
#include <arpa/inet.h>
#include <sys/socket.h>
#include <ifaddrs.h>
#include <stdio.h>
int main ()
{
struct ifaddrs *ifap, *ifa;
struct sockaddr_in *sa;
char *addr;
getifaddrs (&ifap);
for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
if (ifa->ifa_addr->sa_family==AF_INET) {
sa = (struct sockaddr_in *) ifa->ifa_netmask;
addr = inet_ntoa(sa->sin_addr);
printf("Interface: %s\tAddress: %s\n", ifa->ifa_name, addr);
}
}
freeifaddrs(ifap);
return 0;
}
Output
Interface: lo Address: 255.0.0.0
Interface: eth0 Address: 255.255.255.0
In windows using IPHelper.
#include <winsock2.h>
#include <iphlpapi.h>
#include <stdio.h>
#include <stdlib.h>
#pragma comment(lib, "IPHLPAPI.lib")
#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
/* Note: could also use malloc() and free() */
int __cdecl main()
{
PIP_ADAPTER_INFO pAdapterInfo;
ULONG ulOutBufLen = sizeof (IP_ADAPTER_INFO);
pAdapterInfo = (IP_ADAPTER_INFO *) MALLOC(sizeof (IP_ADAPTER_INFO));
GetAdaptersInfo(pAdapterInfo, &ulOutBufLen);
printf("\tIP Mask: \t%s\n", pAdapterInfo->IpAddressList.IpMask.String);
}
if (pAdapterInfo)
FREE(pAdapterInfo);
return 0;
}
Borrowed code from Linux Man page and referred to the code from Keine Lust:
#define _GNU_SOURCE /* To get defns of NI_MAXSERV and NI_MAXHOST */
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netdb.h>
#include <ifaddrs.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/if_link.h>
#include <string.h> /* strcasecmp() */
int get_addr_and_netmask_using_ifaddrs(const char* ifa_name,
char *addr, char *netmask)
{
struct ifaddrs *ifap, *ifa;
struct sockaddr_in *sa;
char *s;
int found = 0;
if (getifaddrs(&ifap) == -1) {
perror("getifaddrs");
exit(EXIT_FAILURE);
}
for (ifa = ifap; ifa && !found; ifa = ifa->ifa_next) {
if (ifa->ifa_addr == NULL)
continue;
if (strcasecmp(ifa_name, ifa->ifa_name))
continue;
/* IPv4 */
if (ifa->ifa_addr->sa_family != AF_INET)
continue;
sa = (struct sockaddr_in *) ifa->ifa_addr;
s = inet_ntoa(sa->sin_addr);
strcpy(addr, s);
sa = (struct sockaddr_in *) ifa->ifa_netmask;
s = inet_ntoa(sa->sin_addr);
strcpy(netmask, s);
found = 1;
}
freeifaddrs(ifap);
if (found)
return EXIT_SUCCESS;
return EXIT_FAILURE;
}
int main(void)
{
char *addr = malloc(NI_MAXHOST);
char *netmask = malloc(NI_MAXHOST);
if (!get_addr_and_netmask_using_ifaddrs ("enp6s0", addr, netmask))
printf("[%s]%s %s\n", __func__, addr, netmask);
else
printf("interface error.\n");
free(addr);
free(netmask);
return 0;
}
Want to do client-server programming using c in windows7, it should send string to server using http POST method. The paramater in POST method should include the ip-address etc:
I got this code from http://souptonuts.sourceforge.net/code/http_post.c.html and changed it for running it on windows, but still 1 error is coming:
#ifdef WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/wait.h>
#include <netdb.h>
#include <assert.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <ctype.h>
#define SA struct sockaddr
#define MAXLINE 4096
#define MAXSUB 200
#define LISTENQ 1024
extern int h_errno;
ssize_t process_http(int sockfd, char *host, char *page, char *poststr)
{
char sendline[MAXLINE + 1], recvline[MAXLINE + 1];
ssize_t n;
snprintf(sendline, MAXSUB,
"POST %s HTTP/1.0\r\n"
"Host: %s\r\n"
"Content-type: application/x-www-form-urlencoded\r\n"
"Content-length: %d\r\n\r\n"
"%s", page, host, strlen(poststr), poststr);
write(sockfd, sendline, strlen(sendline));
while ((n = read(sockfd, recvline, MAXLINE)) > 0) {
recvline[n] = '\0';
printf("%s", recvline);
}
return n;
}
int main(void)
{
int sockfd;
struct sockaddr_in servaddr;
char **pptr;
//********** You can change. Puy any values here *******
char *hname = "souptonuts.sourceforge.net";
char *page = "/chirico/test.php";
char *poststr = "mode=login&user=test&password=test\r\n";
//*******************************************************
char str[50];
struct hostent *hptr;
if ((hptr = gethostbyname(hname)) == NULL) {
fprintf(stderr, " gethostbyname error for host: %s: %s",
hname, hstrerror(h_errno));
exit(1);
}
printf("hostname: %s\n", hptr->h_name);
if (hptr->h_addrtype == AF_INET
&& (pptr = hptr->h_addr_list) != NULL) {
printf("address: %s\n",
inet_ntop(hptr->h_addrtype, *pptr, str,
sizeof(str)));
} else {
fprintf(stderr, "Error call inet_ntop \n");
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
// bzero(&servaddr, sizeof(servaddr));
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(80);
inet_pton(AF_INET, str, &servaddr.sin_addr);
connect(sockfd, (SA *) & servaddr, sizeof(servaddr));
process_http(sockfd, hname, page, poststr);
close(sockfd);
exit(0);
}
The error which is coming on MinGW compiler is:
httppost.c:33:12: error: conflicting types for 'WSAGetLastError'
In file included from httppost.c:5:0:
c:\mingw\bin\../lib/gcc/mingw32/4.7.2/../../../../include/winsock2.h:594:32: n
e: previous declaration of 'WSAGetLastError' was here
The code you've got is under linux based systems, but in MinGW (Windows) unfortunately the identifier h_errno is taken before.
The problem is this line
extern int h_errno;
it's defined previously in windows header files, then you can not use it:
#define h_errno WSAGetLastError()
Just use another identifier instead of h_errno, or even just remove that line!
Maybe you should try the wininet library.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa383630(v=vs.85).aspx