I am writing in windows, using Visual Studio, and am trying to have one application use UDP sockets to broadcast a message to other applications. This must be done with UDP sockets.
It works well with just one client, but it does not when I add another client, and all listen on the same port.
TX (Server)
/* Example from: http://matrixsust.blogspot.com/2011/10/udp-server-client-in-c.html */
/* Use legacy sockets */
#define _WINSOCK_DEPRECATED_NO_WARNINGS
/* Add a linker to ws2_32.lib, the Winsock2 library */
#pragma comment(lib, "ws2_32.lib")
#include <stdio.h>
#include <winsock2.h>
int main()
{
WSADATA wsaData;
int sock, sin_size;
struct sockaddr_in server_addr;
struct hostent* host;
char send_data[1024];
boolean keep_running = 1;
unsigned int cmd_no_block_arg = 1;
int SERVER_PORT;
/* Obtain a valid port */
printf("Enter a port number to connect to (i.e. 7171):\n");
scanf_s("%d", &SERVER_PORT);
if ((SERVER_PORT < 1) || (SERVER_PORT > 665534))
{
SERVER_PORT = 7171;
}
/* Initialize Winsock version 2.2 */
WSAStartup(MAKEWORD(2, 2), &wsaData);
/* CLIENT SIDE */
host = (struct hostent*) gethostbyname((char*)"127.0.0.1");
if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
{
perror("socket");
exit(1);
}
/* SETUP */
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
server_addr.sin_addr = *((struct in_addr*)host->h_addr);
memset(server_addr.sin_zero, 0, sizeof(server_addr.sin_zero));
sin_size = sizeof(struct sockaddr);
/* Bind the socket, then enable non-blocking semantics */
if ((ioctlsocket(sock, FIONBIO, &cmd_no_block_arg) == SOCKET_ERROR))
{
printf("Could not non-bind socket. Error Code %i\n", WSAGetLastError());
}
while (keep_running)
{
printf("Type Something (q or Q to quit):");
gets_s(send_data, sizeof(send_data));
if ((strcmp(send_data, "q") == 0) || strcmp(send_data, "Q") == 0)
{
keep_running = 0;
}
else
{
sendto(sock, send_data, strlen(send_data), 0, (struct sockaddr*) & server_addr, sizeof(struct sockaddr));
}
} // While
}
RX (Clients)
/* Example from: http://matrixsust.blogspot.com/2011/10/udp-server-client-in-c.html */
#define _WINSOCK_DEPRECATED_NO_WARNINGS
/* Add a linker to ws2_32.lib, the Winsock2 library */
#pragma comment(lib, "ws2_32.lib")
#include <stdio.h>
#include <winsock2.h>
#include <sys/types.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
int main()
{
WSADATA wsaData;
int sock;
int addr_len, bytes_read;
char recv_data[1024], send_data[1024];
struct sockaddr_in server_addr, client_addr;
int sharing_flag = 1; /* Allow sharing */
unsigned int non_block_flag = 1;
unsigned int SERVER_PORT = 7171;
/* Obtain a valid port to connect to */
printf("Enter a port number to connect to (i.e. 7171):\n");
scanf_s("%d", &SERVER_PORT);
if ((SERVER_PORT < 1) || (SERVER_PORT > 65535))
{
SERVER_PORT = 7171;
}
/* Initialize Winsock version 2.2 */
WSAStartup(MAKEWORD(2, 2), &wsaData);
/* SERVER SIDE: bind(), recvfrom(), sendto() */
if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
perror("Socket");
exit(1);
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
server_addr.sin_addr.s_addr = INADDR_ANY;
memset(server_addr.sin_zero, 0, sizeof(server_addr.sin_zero));
/* Eliminates "ERROR on binding: Address already in use" error */
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*)&sharing_flag, sizeof(sharing_flag)) == SOCKET_ERROR)
{
printf("Error on socket opt: %i\n", WSAGetLastError());
}
if ((bind(sock, (struct sockaddr*) & server_addr, sizeof(struct sockaddr)) == SOCKET_ERROR) ||
(ioctlsocket(sock, FIONBIO, &non_block_flag) == SOCKET_ERROR))
{
printf("Error on socket bind: %i\n", WSAGetLastError());
}
addr_len = sizeof(struct sockaddr);
printf("\nUDPServer Waiting for client on port %i\n", SERVER_PORT);
while (1)
{
bytes_read = recvfrom(sock, recv_data, 1024, 0, (struct sockaddr*) & client_addr, &addr_len);
if (bytes_read >= 0)
{
recv_data[bytes_read] = '\0';
printf("\n(%s , %d) said : ", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
printf("%s\n", recv_data);
fflush(stdout);
} /* if we read in bytes */
} /* while */
return 0;
}
Related
I'm trying to receive some data from my client and my server appears to hang when it hits the recvfrom() function. I can't tell what's going wrong or if something is potentially wrong with my socket setup. I've coded this in Python too and it works fine and appears the sockets are setup the same. Below is the full code in question, with the hanging happening at the bottom. I'm new to C so apologies for any confusion or idiocy. Thanks so much in advance for any help.
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define WIN32_LEAN_AND_MEAN
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")
#include <winsock2.h>
#include <Ws2tcpip.h>
#include < ws2ipdef.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define PORT 25678
#define STREAM "235.5.4.5"
int main(int argc, char* argv[]) {
int sockfd;
struct sockaddr_in sin, group;
int sin_len, done;
const int buffer_len = 1024;
char buffer[1024];
WSADATA wsaData;
printf("Initializing the winsock library ... ");
if (WSAStartup(MAKEWORD(1, 1), &wsaData) == SOCKET_ERROR) {
return -1;
}
memset(&sin, 0, sizeof(sin));
//1 create a socket
printf("Creating a socket ... ");
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == -1) { perror("Error opening socket"); exit(1); }
//2 set generic socket options
u_int share;
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &share, sizeof(share)) < 0) {
perror("setsockopt"); exit(1);
}
//3 bind the socket to the port
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
sin.sin_addr.s_addr = htonl(INADDR_ANY);
sin_len = sizeof(sin);
if (bind(sockfd, (struct sockaddr*)&sin, sin_len) < 0) {
exit(1);
};
//4 set up mreq
group.sin_family = AF_INET;
group.sin_port = htons(PORT);
group.sin_addr.s_addr = inet_addr(STREAM);
struct ip_mreq mreq;
mreq.imr_multiaddr = group.sin_addr;
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
//5 set the socket options to the mreq
if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) {
printf("ERROR adding membership");
exit(1);
}
done = 0;
int nb;
//6 listen
while (!done) {
//int recvfrom(int socket, char *buf, int buflen, int flags, struct sockaddr* addr, int* addrlen);
nb = recvfrom(sockfd, (char*)buffer, buffer_len, 0, (struct sockaddr*)&sin, &sin_len);
}
close(sockfd);
return(0);
}
I have this funny little problem in two nearly identical programs. What I am trying to do is send some data on Multicast socket and receive it. For now, I am okay if the sender receives the message (I'll set the option to not receive later).
I have two implementation cases. In the first approach, I am using the traditional way of initializing a sockaddr structure and then binding to, and also joining a multicast group on the same socket. This, however, is IPv4/IPv6 dependent and to circumvent that, I tried to use addrinfo structures in the second variant of the program. Both programs are given below.
The problem is, the messages are being received in the first use case, where I am using the regular sockaddr while, there is no message being received/socket descriptor being set in the second case. Could somebody help me out and explain why is this happening?
Variant 1 (with sockaddr)
#include<stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/param.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>
#include <fcntl.h> /* for nonblocking */
#include <netinet/tcp.h>
fd_set hm_tprt_conn_set;
main()
{
struct ip_mreq mreq;
struct sockaddr_in mc_addr;
int sock_fd ;
int val;
int reuse = 1;
struct sockaddr_in ip;
struct sockaddr_in src_addr;
int total_bytes_rcvd=0;
unsigned int length;
unsigned char buf[50];
int op_complete = 0;
int os_error;
struct timeval select_timeout;
fd_set read_set;
int32_t nready; //Number of ready descriptors
time_t time_val;
length = sizeof (src_addr);
sock_fd = socket(AF_INET, SOCK_DGRAM,0);
if(sock_fd == -1)
{
printf("\n Error Opening UDP MCAST socket");
perror("\n Cause is ");
exit(0);
}
printf("\n Setting the socket to non-blocking mode");
val = fcntl(sock_fd, F_GETFL , 0);
val = fcntl(sock_fd, F_SETFL, val | O_NONBLOCK);
if (val == -1)
{
printf("\n Error while setting socket to non-blocking mode");
perror("Cause is ");
sock_fd = -1;
exit(0);
} //end if val == -1
if (setsockopt(sock_fd,SOL_SOCKET,SO_REUSEADDR, &reuse, sizeof(reuse)) == -1)
{
fprintf(stderr, "setsockopt: %d\n", errno);
perror("Cause is ");
exit(0);
}
FD_SET(sock_fd, &hm_tprt_conn_set);
printf("\n Construct a mcast address structure");
/* construct a multicast address structure */
memset(&mc_addr, 0, sizeof(mc_addr));
mc_addr.sin_family = AF_INET;
mc_addr.sin_addr.s_addr = htonl(INADDR_ANY);
mc_addr.sin_port = htons(4936);
memset(&ip, 0, sizeof(ip));
ip.sin_family = AF_INET;
ip.sin_addr.s_addr = inet_addr("224.0.0.203")/*htonl(INADDR_ANY)*/;
ip.sin_port = htons(4936);
printf("\n Bind the multicast address structure and port to the recieving socket ");
if (bind( sock_fd, (struct sockaddr*) &mc_addr, sizeof(mc_addr)) == -1)
{
fprintf(stderr, "bind: %d\n", errno);
perror("\n Cause is ");
exit(0);
}
mreq.imr_multiaddr.s_addr = inet_addr("224.0.0.203");
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
if(setsockopt(sock_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,&mreq, sizeof(mreq)) == -1)
{
fprintf(stderr, "setsockopt: %d\n", errno);
perror("\n Cause is ");
exit(0);
}
printf("\nCreated Recv Socket: %d", sock_fd);
fflush(stdout);
memset(&src_addr, 0, sizeof(mc_addr));
while(1){
/* Send a multicast */
time_val = time(NULL);
snprintf(buf, sizeof(buf), "Hello: %s", ctime(&time_val));
total_bytes_rcvd = sendto(sock_fd,
buf,
sizeof(buf),
0,
(struct sockaddr *)&ip,
length );
printf("\n%d bytes sent.", total_bytes_rcvd);
/* perform select */
select_timeout.tv_sec = 0;
select_timeout.tv_usec = 5000000;
read_set = hm_tprt_conn_set;
nready = select(sock_fd+1, &read_set, NULL, NULL, &select_timeout);
if(nready == 0)
{
/***************************************************************************/
/* No descriptors are ready */
/***************************************************************************/
continue;
}
else if(nready == -1)
{
perror("Error Occurred on select() call.");
continue;
}
if(FD_ISSET(sock_fd, &read_set))
{
printf("\n Recv the data");
total_bytes_rcvd = recvfrom(sock_fd,
buf,
sizeof(buf),
0,
(struct sockaddr *)&src_addr,
&length );
printf("%s: message = \" %s \"\n", inet_ntoa(src_addr.sin_addr), buf);
printf("\n total byte recieved %d", total_bytes_rcvd);
/***************************************************************************/
/* If select returned 1, and it was a listen socket, it makes sense to poll*/
/* again by breaking out and use select again. */
/***************************************************************************/
if(--nready <=0)
{
printf("\nNo more incoming requests.");
continue;
}
}//end select on listenfd
}
}
Variant 2 (with addrinfo)
#include<stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/param.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>
#include <fcntl.h> /* for nonblocking */
#include <netinet/tcp.h>
#include <netdb.h> /* AI_PASSIVE and other Macros for getaddrinfo() */
fd_set hm_tprt_conn_set;
main()
{
struct addrinfo hints, *res, *ressave;
char target[128] = "127.0.0.1";
char service[128] = "4936";
struct ip_mreq mreq;
int sock_fd ;
int val;
int reuse = 1;
struct sockaddr_in ip;
struct sockaddr_in src_addr;
int total_bytes_rcvd=0;
unsigned int length;
unsigned char buf[50];
int op_complete = 0;
int os_error;
struct timeval select_timeout;
fd_set read_set;
int32_t nready; //Number of ready descriptors
time_t time_val;
length = sizeof (src_addr);
sock_fd = socket(AF_INET, SOCK_DGRAM,0);
if(sock_fd == -1)
{
printf("\n Error Opening UDP MCAST socket");
perror("\n Cause is ");
exit(0);
}
printf("\n Setting the socket to non-blocking mode");
val = fcntl(sock_fd, F_GETFL , 0);
val = fcntl(sock_fd, F_SETFL, val | O_NONBLOCK);
if (val == -1)
{
printf("\n Error while setting socket to non-blocking mode");
perror("Cause is ");
sock_fd = -1;
exit(0);
} //end if val == -1
if (setsockopt(sock_fd,SOL_SOCKET,SO_REUSEADDR, &reuse, sizeof(reuse)) == -1)
{
fprintf(stderr, "setsockopt: %d\n", errno);
perror("Cause is ");
exit(0);
}
FD_SET(sock_fd, &hm_tprt_conn_set);
printf("\n Construct a mcast address structure");
/* construct a multicast address structure */
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = IPPROTO_UDP;
if((os_error = getaddrinfo(target, service, &hints, &res)) !=0)
{
printf("\n%s",gai_strerror(os_error));
exit(0);
}
ressave = res;
if(bind(sock_fd, res->ai_addr, res->ai_addrlen) != 0)
{
perror("Error binding to port");
close(sock_fd);
sock_fd = -1;
}
mreq.imr_multiaddr.s_addr = inet_addr("224.0.0.203");
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
if(setsockopt(sock_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,&mreq, sizeof(mreq)) == -1)
{
fprintf(stderr, "setsockopt: %d\n", errno);
perror("Cause is ");
exit(0);
}
/* Set Destination address */
memset(&ip, 0, sizeof(ip));
ip.sin_family = AF_INET;
ip.sin_addr.s_addr = inet_addr("224.0.0.203")/*htonl(INADDR_ANY)*/;
ip.sin_port = htons(4936);
/* Set to zero address where addresses of sender will be received */
memset(&src_addr, 0, sizeof(src_addr));
while(1){
/* Send a multicast */
time_val = time(NULL);
snprintf(buf, sizeof(buf), "Hello: %s", ctime(&time_val));
total_bytes_rcvd = sendto(sock_fd,
buf,
sizeof(buf),
0,
(struct sockaddr *)&ip,
length );
printf("\n%d bytes sent.", total_bytes_rcvd);
/* perform select */
select_timeout.tv_sec = 0;
select_timeout.tv_usec = 5000000;
read_set = hm_tprt_conn_set;
nready = select(sock_fd+1, &read_set, NULL, NULL, &select_timeout);
if(nready == 0)
{
/***************************************************************************/
/* No descriptors are ready */
/***************************************************************************/
continue;
}
else if(nready == -1)
{
perror("Error Occurred on select() call.");
continue;
}
if(FD_ISSET(sock_fd, &read_set))
{
printf("\n Recv the data");
total_bytes_rcvd = recvfrom(sock_fd,
buf,
sizeof(buf),
0,
(struct sockaddr *)&src_addr,
&length );
printf("%s: message = \" %s \"\n", inet_ntoa(src_addr.sin_addr), buf);
printf("\n total byte recieved %d", total_bytes_rcvd);
/***************************************************************************/
/* If select returned 1, and it was a listen socket, it makes sense to poll*/
/* again by breaking out and use select again. */
/***************************************************************************/
if(--nready <=0)
{
printf("\nNo more incoming requests.");
continue;
}
}//end select on listenfd
}
}
The difference is that in the first variant you're binding to INADDR_ANY, while in the second variant you're binding to 127.0.0.1. Failing to bind to INADDR_ANY means you won't receive any multicast data.
You can fix this with the following:
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = IPPROTO_UDP;
hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV;
if((os_error = getaddrinfo(NULL, service, &hints, &res)) !=0)
{
printf("\n%s",gai_strerror(os_error));
exit(0);
}
From the man page for getaddrinfo regarding AI_PASSIVE:
If node is NULL, the network address in each socket structure is initialized according to the AI_PASSIVE flag, which is set in
hints.ai_flags. The network address in each socket structure will be
left unspecified if AI_PASSIVE flag is set. This is used by server
applications, which intend to accept client connections on any network
address. The network address will be set to the loopback interface
address if the AI_PASSIVE flag is not set. This is used by client
applications, which intend to connect to a server running on the same
network host.
While in this case you are sending to the same host, multicast data does not go out on the localhost interface by default. You would need to call setsockopt with the IP_MULTICAST_IF option to set the outgoing multicast interface.
With this change, I was able to send and receive with the second variant.
Before you can bind() you need to have a working socket. You will need to cycle through all the results. Here's what's missing on your code.
ressave = res;
sock = socket(ressave->ai_family, ressave->ai_socktype, ressave->ai_protocol);
while(ressave != NULL && (sock < 0 || connect(sock, ressave->ai_addr, ressave->ai_addrlen) < 0)) {
close(sock);
if((ressave = ressave->ai_next) != NULL)
sock = socket(ressave->ai_family, ressave->ai_socktype, ressave->ai_protocol);
}
At this point you have either found a working socket sock or not. When ressave is not NULL then the value of socket sock is valid.
I've been scratching my head with this one for quite a while now. I've got a simple client and server program and I want the server to echo what the client sends it. I can't figure out why the server isn't receiving any data.
Client code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define MAX_BUF 64
#define MAX_ARGS 8
void initClient(int*);
int main()
{
int socket;
/* initialize socket and connect to server */
initClient(&socket);
while(1){
char in[80];
char temp[80];
bzero(in, 80);
bzero(temp, 80);
printf("What's your message: ");
gets(in);
strcpy(temp, in);
send(socket, temp, strlen(temp), 0);
if(strcmp(temp, "exit") == 0)
break;
}
return 0;
}
void initClient(int *sock)
{
FILE *configFile;
char ip[MAX_BUF];
int port;
int i;
struct sockaddr_in addr;
/* get IP address and port number from config file */
if (!(configFile=fopen(".config","r"))) {
printf("cannot read config file...\n");
exit(1);
}
fscanf(configFile, "%s", ip);
fscanf(configFile, "%d", &port);
fclose(configFile);
/* create socket and connect to logger */
sock = (int *)socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if(sock < 0){
printf("Could not open socket\n");
exit(-1);
}
/* setup address */
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(ip);
addr.sin_port = htons((unsigned short) port);
/* connect to server */
i = connect((int)sock,
(struct sockaddr *) &addr,
sizeof(addr));
if (i<0) {
printf("client could not connect!\n");
exit(-1);
}
}
Server code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define MAX_BUF 64
int main()
{
FILE *configFile;
char ip[MAX_BUF];
int port;
char str[MAX_BUF];
/* get IP address and port number from config file */
if (!(configFile=fopen(".config","r"))) {
printf("cannot read config file...\n");
exit(1);
}
fscanf(configFile, "%s", ip);
fscanf(configFile, "%d", &port);
fclose(configFile);
int myListenSocket, clientSocket;
struct sockaddr_in myAddr, clientAddr;
int i, addrSize, bytesRcv;
/* Create socket */
myListenSocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if(myListenSocket < 0) {
printf("Couldn't open socket\n");
exit(-1);
}
/* Set up server address */
memset(&myAddr, 0, sizeof(myAddr));
myAddr.sin_family = AF_INET;
myAddr.sin_addr.s_addr = htonl(INADDR_ANY);
myAddr.sin_port = htons((unsigned short) port);
/* Binding */
i = bind(myListenSocket, (struct sockaddr *) &myAddr, sizeof(myAddr));
if(i < 0){
printf("Couldn't bind socket\n");
exit(-1);
}
/* Listen */
i = listen(myListenSocket, 5);
if(i < 0){
printf("Couldn't listen\n");
exit(-1);
}
/* Wait for connection request */
addrSize = sizeof(clientAddr);
clientSocket = accept(myListenSocket,
(struct sockaddr *) &clientAddr,
&addrSize);
if(clientSocket < 0){
printf("Couldn't accept the connection\n");
exit(-1);
}
/* Read message from client and do something with it */
char buffer[100];
while(1){
bzero(buffer, 100);
bytesRcv = read(clientSocket, buffer, sizeof(buffer));
buffer[bytesRcv] = 0;
printf("this is what the client sent: %s\n", buffer);
if(bytesRcv == 0){
break;
}
}
close(myListenSocket);
close(clientSocket);
return 0;
}
When you pass a pointer you should reference it as *sock to get its value, otherwise if you reference it as sock you are, in fact, getting the address and not the value of the variable.
Here is your initClient function corrected:
void initClient(int *sock)
{
FILE *configFile;
char ip[128];
int port;
int i;
struct sockaddr_in addr;
/* get IP address and port number from config file */
if (!(configFile=fopen(".config","r"))) {
printf("cannot read config file...\n");
exit(1);
}
fscanf(configFile, "%s", ip);
fscanf(configFile, "%d", &port);
fclose(configFile);
/* create socket and connect to logger */
*sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if(*sock < 0){
printf("Could not open socket\n");
exit(-1);
}
/* setup address */
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(ip);
addr.sin_port = htons((unsigned short) port);
/* connect to server */
i = connect(*sock, (struct sockaddr *) &addr, sizeof(addr));
if (i<0) {
printf("client could not connect!\n");
exit(-1);
}
}
I'm trying to make a server and client. But when I try to connect the client to the server, I get connection refused. The other answers on stack overflow said to make sure you have listen() and accept(), which I do, and to check the firewalls. So I turned off all the firewalls just to make sure.
I still get connection refused, so I tried ./telnet 10.1.10.13 9696, and got:
Trying 10.1.10.13...
telnet: connect to address 10.1.10.13: Connection refused
telnet: Unable to connect to remote host
Here's the code for the server
int setUpServer(struct fuzzerObj *ptr)
{
/* Declarations */
int hostSocket, yes = 1, rtrn;
union
{
struct sockaddr_in in;
}address;
/* Create Socket */
hostSocket = socket(AF_INET, SOCK_STREAM, 0);
if(hostSocket < 0)
{
errorHandler("Could not create socket\n", FUNCTION_ID_SET_UP_SERVER);
return -1;
}
/* Reuse Address */
rtrn = setsockopt(hostSocket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
if(rtrn < 0)
{
errorHandler("Couldn't Reuse Address\n", FUNCTION_ID_SET_UP_SERVER);
return -1;
}
errno = 0;
/* Set Up Struct */
address.in.sin_len = sizeof(address.in);
address.in.sin_family = AF_INET;
address.in.sin_port = BBPORT_NUMBER;
address.in.sin_addr.s_addr = htonl(INADDR_ANY);
memset(address.in.sin_zero, 0, sizeof(address.in.sin_zero));
/* Bind Address to Socket */
rtrn = bind(hostSocket, (struct sockaddr*) &address, address.in.sin_len);
if(rtrn < 0)
{
errorHandler("Can't Bind Address to Socket\n", FUNCTION_ID_SET_UP_SERVER);
perror("");
return -1;
}
/* listen */
rtrn = listen(hostSocket, ptr->numberOfClients);
if(rtrn < 0)
{
errorHandler("Can't Listen\n", FUNCTION_ID_SET_UP_SERVER);
return -1;
}
while(1) acceptClient(hostSocket);
return 0;
}
int acceptClient(int fd)
{
struct sockaddr_storage addr;
socklen_t addr_len = sizeof(addr);
int clientFd = accept(fd, (struct sockaddr *) &addr, &addr_len);
if(clientFd < 0)
{
printf("Can't Accept Client\n");
return -1;
}
return clientFd;
}
and the code for the client:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdbool.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#define BLACKBOX_PORT 9696
int main(int argc, char *argv[])
{
/* Check To See If an argument was passed */
if(argc < 2)
{
printf("No enough Arguments\n");
return -1;
}
/* Declaration's */
const char *ip = argv[1];
int sockfd, fd, rtrn;
char *inBuf;
struct sockaddr_in servaddr,cliaddr;
socklen_t len = sizeof(cliaddr);
/* Get Socket to Connect to Fuzz Server */
sockfd = socket(PF_INET, SOCK_STREAM, 0);
if(sockfd < 0)
{
perror("Can't Create Socket");
return -1;
}
/* Fill Out Struct */
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(BLACKBOX_PORT);
inet_pton(AF_INET, ip, &servaddr.sin_addr);
/* Attempt Connection */
fd = connect(sockfd,(struct sockaddr *)&servaddr, sizeof(servaddr));
if(fd < 0)
{
perror("Can not connect to BlackBox Fuzz server");
return -1;
}
/* Allocate Space in Memory for Incoming Connection */
inBuf = (char *) malloc(1025);
if(inBuf == NULL)
{
perror("Mem Error");
return -1;
}
/* Read From Socket */
rtrn = read(fd, inBuf, 1024);
if(rtrn < 0)
{
perror("Can't Read Data From BlackBox Server");
return -1;
}
printf("Received Data: %s\n", inBuf);
free(inBuf);
return 0;
}
Output from client:
./client 10.1.10.13
Can not connect to BlackBox Fuzz server
Connection refused
Any help would be appreciated, thanks.
Assuming that you're running this code on a little-endian machine, you need to use htons() when assigning the port number on the server side too.
(On big-endian machines htons() is a "no-op", but you should always use it to ensure portability)
I’ve made C programs they are the server and the client. They send message each other by using udp.
The server waits until message is sent from the client.
When I type some message from the client console, the client will send the message to the server.
The serve receives the message from the client then the server will echo the message on its console and send back same message to the client.
Finaly the client shows message on its console that the server sent back the message.
In this procedure the client shows its source port number on its console.And the server also shows client's source port number that message was sent with recvfrom ()
Strangely, source port number is different between the client and the server if I run them on windows7 but if I run them on CentOS6.4 the source port number is same.
Does anyone know how this happens?
My code are following.
[server]
#define _WIN32_WINNT 0x0501
#include <stdio.h>
#include <sys/types.h>
#include <WinSock2.h>
#include <WS2tcpip.h>
#include <string.h>
int charToInt(char myText[]) {
char s[] = {'1', '2', '3', '4'};
const int n = strlen(myText);
int i, m = 0;
for(i = 0; i < n; ++ i){
m = m * 10 + myText[i] - '0';
}
printf("%d\n", m);
return m;
}
int
main(int argc,char *argv[])
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2,2), &wsaData);
int sock;
struct sockaddr_in addr;
struct sockaddr_in from;
int sockaddr_in_size = sizeof(struct sockaddr_in);
char buf[2048];
char comnd[2048];
char *bye="bye";
printf("############# udpServer start prot number is %d\n",charToInt(argv[1]));
sock = socket(AF_INET, SOCK_DGRAM, 0);
addr.sin_family = AF_INET;
addr.sin_port = htons(charToInt(argv[1]));
addr.sin_addr.s_addr = INADDR_ANY;
bind(sock, (struct sockaddr *)&addr, sizeof(addr));
while (!strncmp(buf,bye,3)==0){
memset(buf, 0, sizeof(buf));
recvfrom(sock, buf, sizeof(buf), 0,(struct sockaddr *)&from, &sockaddr_in_size);
printf("recived '%s'(%d) from %s:%d\n", buf, strlen(buf),
inet_ntoa(from.sin_addr),ntohs(from.sin_port));
sendto(sock, buf, sizeof(buf), 0, (struct sockaddr *)&from, sizeof(from));
printf("send back %s to %s:%d\n", buf,inet_ntoa(from.sin_addr),ntohs(from.sin_port));
printf("\n");
}
printf("bye now");
close(sock);
return 0;
}
[client]
#define _WIN32_WINNT 0x0501
#include <stdio.h>
#include <sys/types.h>
#include <WinSock2.h>
#include <WS2tcpip.h>
#include <string.h>
#include <errno.h>
int charToInt(char myText[]) {
char s[] = {'1', '2', '3', '4'};
const int n = strlen(myText);
int i, m = 0;
for(i = 0; i < n; ++ i){
m = m * 10 + myText[i] - '0';
}
printf("%d\n", m);
return m;
}
int getMyPortNum(int sock)
{
struct sockaddr_in s;
socklen_t sz = sizeof(s);
getsockname(sock, (struct sockaddr *)&s, &sz);
return s.sin_port;
}
int
main(int agrc,char *argv[])
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2,2), &wsaData);
char *host;
int port;
int sock;
struct sockaddr_in dst_addr = {0};
struct sockaddr_in src_addr = {0};
struct sockaddr_in rcv_addr = {0};
int sockaddr_in_size = sizeof(struct sockaddr_in);
int defPortNum;
char message[2048];
char comnd[2048];
int i;
int ret;
int connect_ret;
int bind_ret;
char *p;
char buf[2048];
host=argv[1];
port=charToInt(argv[2]);
printf("host = %s\n",host);
printf("port = %d\n",port);
sock = socket(AF_INET, SOCK_DGRAM, 0);
dst_addr.sin_family = AF_INET;
dst_addr.sin_addr.s_addr = inet_addr(host);
dst_addr.sin_port = htons(port);
printf("getMyPortNum before bind() is %d\n",ntohs(src_addr.sin_port));
bind_ret = 0;
bind_ret = bind(sock,(struct sockaddr *)&src_addr,sizeof(src_addr));
src_addr.sin_port = getMyPortNum(sock);
printf("Default Client port is %d\n",ntohs(src_addr.sin_port));
if(bind_ret>=0){
printf("bind() error ret = %d:%s\n",bind_ret,strerror(errno));
perror("bind()");
return bind_ret;
}
memset(message, 0, sizeof(message));
memset(comnd, 0, sizeof(comnd));
memset(buf,0,sizeof(buf));
while(!strncmp(comnd,"bye",3)==0){
if(strncmp(message,"bye",3)==0){
strcpy(comnd,message);
}else{
printf("typ your message (exit:stop Client bye:stop server)>>>\t");
fgets(comnd,sizeof(comnd),stdin);
comnd[strlen(comnd) - 1] = '\0';
strcpy(message,comnd);
}
ret = sendto(sock, message, strlen(message), 0,
(struct sockaddr *)&dst_addr, sizeof(dst_addr));
printf("Server port (dst port) for sending is %d\n",ntohs(dst_addr.sin_port));
if(ret<0){
printf("Send Error ret = %d:%s\n",ret,strerror(errno));
return ret;
}else{
printf("Waiting for sendBack !!!\n");
printf("Client port for recieving is %s:%d\n"
,inet_ntoa(src_addr.sin_addr),ntohs(src_addr.sin_port));
ret = recvfrom(sock, buf, sizeof(buf),
0,(struct sockaddr *)&rcv_addr, &sockaddr_in_size);
if(ret<0){
printf("ReciveError ret = %d\n",ret);
}else{
printf("Sentback %s from %s:%d\n"
,buf,inet_ntoa(rcv_addr.sin_addr)
,ntohs(rcv_addr.sin_port));
}
}
}
close(sock);
}
It is possible that a new random source port gets used every time you call sendto(), unless you explicitly bind() the client socket to a specific source port (and not rely on the OS doing an implicit bind() for you). That is the only reliable way the client could display its own source port, since sendto() does not report the source port that is actually used. Remember, unlike TCP, UDP is connection-less, so the source port is not required to stay consistent unless you force it.
Update: your client code has one line where it is logging a network byte order port number when it should be logging a host byte order port number instead:
//printf("getMyPortNum before bind() is %d\n",myName.sin_port);
printf("getMyPortNum before bind() is %d\n",port);
Aside from that, why did you create your own charToInt() function, instead of using a standard function, like atoi() or strtol()?
You are also not doing very good error handling.
Try something more like this instead:
[Server]
#define _WIN32_WINNT 0x0501
#include <stdio.h>
#include <sys/types.h>
#include <WinSock2.h>
#include <WS2tcpip.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
int printerror2(char func[], int errnum)
{
printf("%s error = %d:%s\n", func, errnum, strerror(errnum));
perror(func);
return errnum;
}
int printerror(char func[])
{
return printerror2(func, errno);
}
int main(int argc, char *argv[])
{
WSADATA wsaData;
int ret = WSAStartup(MAKEWORD(2,2), &wsaData);
if (ret != 0)
return printerror2("WSAStartup()", ret);
int sock;
in_port_t port;
struct sockaddr_in addr;
struct sockaddr_in from;
int from_size;
char buf[2048];
port = atoi(argv[1]);
printf("############# udpServer port number is %hu\n", port);
sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sock == -1)
return printerror("socket()");
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = INADDR_ANY;
ret = bind(sock, (struct sockaddr *)&addr, sizeof(addr));
if (ret == -1)
return printerror("bind()");
do
{
from_size = sizeof(from);
ret = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *)&from, &from_size);
if (ret == -1)
return printerror("recvfrom()");
printf("received '%*s'(%d) from %s:%hu\n",
ret, buf, ret, inet_ntoa(from.sin_addr), ntohs(from.sin_port));
ret = sendto(sock, buf, ret, 0, (struct sockaddr *)&from, from_size);
if (ret == -1)
return printerror("sendto()");
printf("sent back '%*s'(%d) to %s:%hu\n",
ret, buf, ret, inet_ntoa(from.sin_addr), ntohs(from.sin_port));
printf("\n");
}
while ((ret != 3) || (strncmp(buf, "bye", 3) != 0));
printf("bye now");
close(sock);
return 0;
}
[Client]
#define _WIN32_WINNT 0x0501
#include <stdio.h>
#include <sys/types.h>
#include <WinSock2.h>
#include <WS2tcpip.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
int printerror2(char func[], int errnum)
{
printf("%s error = %d:%s\n", func, errnum, strerror(errnum));
perror(func);
return errnum;
}
int printerror(char func[])
{
return printerror2(func, errno);
}
int getMyPortNum(int sock, in_port_t *port)
{
struct sockaddr_in s;
socklen_t sz = sizeof(s);
int ret = getsockname(sock, (struct sockaddr *)&s, &sz);
if (ret == 0)
*port = s.sin_port;
return ret;
}
int main(int agrc, char *argv[])
{
WSADATA wsaData;
int ret = WSAStartup(MAKEWORD(2,2), &wsaData);
if (ret != 0)
return printerror2("WSAStartup", ret);
char *host;
in_port_t port;
int sock;
struct sockaddr_in dst_addr;
struct sockaddr_in src_addr;
struct sockaddr_in from_addr;
int from_size;
char buf[2048];
host = argv[1];
port = atoi(argv[2]);
printf("host = %s\n", host);
printf("port = %hu\n", port);
sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sock == -1)
return printerror("socket()");
memset(&src_addr, 0, sizeof(src_addr));
src_addr.sin_family = AF_INET;
src_addr.sin_addr.s_addr = INADDR_ANY;
src_addr.sin_port = 0;
ret = bind(sock, (struct sockaddr *)&src_addr, sizeof(src_addr));
if (ret == -1)
return printerror("bind()");
ret = getMyPortNum(sock, &(src_addr.sin_port));
if (ret == -1)
return printerror("getsockname()");
printf("Client port is %hu\n", ntohs(src_addr.sin_port));
memset(&dst_addr, 0, sizeof(dst_addr));
dst_addr.sin_family = AF_INET;
dst_addr.sin_addr.s_addr = inet_addr(host);
dst_addr.sin_port = htons(port);
do
{
printf("type your message (exit: stop Client, bye: stop server)>>>\t");
fgets(buf, sizeof(buf), stdin);
if (strcmp(buf, "exit") == 0)
break;
ret = sendto(sock, buf, strlen(buf), 0, (struct sockaddr *)&dst_addr, sizeof(dst_addr));
if (ret == -1)
return printerror("sendto()");
printf("Waiting for send back !!!\n");
from_size = sizeof(from_addr);
ret = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *)&from_size, &from_size);
if (ret == -1)
return printerror("recvfrom()");
printf("Received '%*s' from %s:%hu\n",
ret, buf, inet_ntoa(from_addr.sin_addr), ntohs(from_addr.sin_port));
}
while ((ret != 3) || (strncmp(buf, "bye", 3) != 0));
close(sock);
return 0;
}
return s.sin_port;
That should be
return ntohs(s.sin_port);
It works in CentOS presumably because 'ntohs(i) == i' there.