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);
}
Related
So here is the code, code successfully compiles...
#include <stdio.h> // for printf
#include <linux/if_tun.h> //for IFF_TUN
#include <sys/socket.h> //socket, struct sockaddr_in
#include <fcntl.h> // for O_RDWR macros
#include <string.h> //for strcpy
#include <unistd.h> //for read();
#include <netdb.h> //for struct sockaddr
#include <net/if.h> //struct ifreq and IFNAMSIZ and other macros
#include <errno.h>
#include <stdlib.h>
// _check: error handler
static int _check(int retval, const char *msg)
{
if(retval == -1)
{
fprintf(stderr, "%s: %s\n", msg, strerror(errno));
exit(EXIT_FAILURE);
}
return retval;
}
int tcp_listen_sock(int listen_connection)
{
/*-------------------------socket-----------------------*/
int sock, tcp_sock;
struct addrinfo hints, *result;
struct sockaddr *addrin;
memset(&hints ,0 , sizeof(hints));
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
const char *host;
host = "0.0.0.0";
_check(getaddrinfo(host, NULL, &hints, &result), "getaddrinfo");
if (result->ai_family == AF_INET)
((struct sockaddr_in *)result->ai_addr)->sin_port = htons(5678);
else if (result->ai_family == AF_INET6)
((struct sockaddr_in6 *)result->ai_addr)->sin6_port = htons(5678);
else {
fprintf(stderr, "unknown ai_family %d", result->ai_family);
freeaddrinfo(result);
return -1;
}
memcpy(addrin, result->ai_addr, result->ai_addrlen);
// *client_len = result->ai_addrlen;
_check((sock = socket(AF_INET, SOCK_STREAM, 0)), "socket");
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "enp0s3");
_check(setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr)), "setsockopt");
int flags;
if((flags = fcntl(sock, F_GETFL)) != -1)
{
fcntl(sock, F_SETFL, flags | O_NONBLOCK);
}
else
perror("socket fcntl");
_check(bind(sock,result->ai_addr, result->ai_addrlen), "tcp bind");
int len = sizeof(struct sockaddr);
_check(listen(sock, listen_connection), "listen");
tcp_sock = accept(sock, result->ai_addr, &result->ai_addrlen );
printf("now listening on tcp!\n");
return tcp_sock;
}
int main(int argc, char **argv)
{
printf("Starting program\n");
int tcp = tcp_listen_sock(5);
printf("ending program\n");
return 0;
}
and ,
OUTPUT
Starting program
now listening on tcp!
ending program
but server socket is not actually listening...
expected output:
Starting program
now listening on tcp!
read...
write...
read...
write...
read...
write..
I can't figure our what I am missing, I know I didn't implemented read, write yet but I will do it after when server socket seems to working fine and listening properly.
NOTE: I am doing this in linux (specifically ubuntu)
Any help will be appreciated...
Calling getaddrinfo to initialize a local list socket seems like overkill.
Start with this. This is a simple "create a listen socket and wait for an incoming TCP connection" code sample.
int tcp_socket_listen(int listen_connection)
{
struct sockaddr_in addr = {0};
sockaddr_in addrRemote = {0};
socklen_t sizeRemote = 0;
int tcp_socket = -1;
s = socket(AF_INET, SOCK_STREAM, 0);
_check(s, "socket");
addr.sin_family = AF_INET;
addr.sin_port = htons(5678);
_check(bind(s, (sockaddr*)&addr, sizeof(addr)), "bind");
_check(listen(sock, listen_connection), "listen");
sizeRemote = sizeof(addrRemote);
tcp_sock = accept(s, (sockaddr*)&addrRemote, &sizeRemote);
_check(tcp_sock, "accept");
printf("now listening on TCP\n");
return tcp_sock;
}
Now if you want to bind to a specific adapter (e.g. "enp0s3") instead of the default ("all adapters") or need IPV6 support, you can peruse my sample code on github here for the GetSocketAddressForAdapter and use that address for the bind call instead of the default addr address above. It's C++, but you can probably port it to straight C with a little work.
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;
}
I'm trying to receive multicast data from an embedded device connected to the same switch as my desktop and am unable to receive multicast messages on my recv app below.
When I do a tcpdump or run Wireshark against the interface connected to the switch, I see the packets show up but for some reason they don't in my app.
I'm using INADDR_ANY for the interface address.
Could someone shed some light on why the messages would be on Wireshark/Tcpdump but not received by the application?
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <string.h>
#include <stdio.h>
#define UDP_PORT 5403
#define UDP_GROUP "225.0.0.1"
#define MAX_BUFFER_SIZE 256
int main(int argc, char *argv[])
{
struct sockaddr_in addr;
int fd, nbytes;
socklen_t addrlen;
struct ip_mreq mreq;
char msgbuf[MAX_BUFFER_SIZE];
u_int reuse_port = 1;
// Create a socket
fd = socket(AF_INET,SOCK_DGRAM,0);
if (fd < 0)
{
perror("create socket failed");
return -1;
}
// allow multiple sockets to use the same PORT number
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse_port, sizeof(reuse_port)) < 0)
{
perror("Reusing port number failed");
return -1;
}
// set up destination address
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(UDP_PORT);
if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
perror("bind");
return -1;
}
// Set the recvfrom timeout after 1 s
struct timeval tv;
tv.tv_sec = 2;
tv.tv_usec = 0;
if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0)
{
perror("Error setting recvfrom timeout\n");
return -1;
}
// use setsockopt() to request that the kernel join a multicast group
mreq.imr_multiaddr.s_addr = inet_addr(UDP_GROUP);
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
{
perror("setsockopt");
return -1;
}
addrlen = sizeof(addr);
printf("Begin recvfrom(...) infinite loop\n");
while (true)
{
nbytes = recvfrom(fd, msgbuf, MAX_BUFFER_SIZE, 0, (struct sockaddr *)&addr, &addrlen);
if (nbytes < 0)
{
printf("recvfrom timeout\n");
}
else
{
printf("message received: %s\n", msgbuf);
}
}
return 1;
}
I wrote a server code as the main server for all the clients. This program is multi-threaded and waits for the clients to connect. Once all the threads are created, they wait on thread accept. Once the connection is accepted, they wait on reception of file from clients. At the end of these threads reception, all the threads join so that system is at common point. This behavior repeats after every 40 seconds.
I need to capture video frames and transferring then integrated in the code?
Server.c
// Server side C/C++ program to demonstrate Socket programming
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#include<pthread.h> //for threading , link with lpthread
#define LISTENING_PORT 8080
#define CLIENT_COUNT 4
void * handle_new_conn(void *server_fd)
{
int valread;
char buffer[1024] = {0};
char *hello = "Hello from server";
int new_socket;
struct sockaddr_in address;
int addrlen = sizeof(address);
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons( LISTENING_PORT );
/* Accept connection from client */
if ((new_socket = accept(*((int *)server_fd),
(struct sockaddr *)&address,
(socklen_t*)&addrlen)) < 0)
{
perror("accept");
exit(EXIT_FAILURE);
}
/* Code to handle new connection */
valread = read(new_socket, buffer, 1024);
printf("%s\n", buffer);
sleep(10);
send(new_socket, hello , strlen(hello), 0);
printf("Hello message sent\n");
sleep(2);
close(new_socket);
}
int main(int argc, char const *argv[])
{
int server_fd, new_socket, valread;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
char buffer[1024] = {0};
char *hello = "Hello from server";
pthread_t thread_id[4];
int client_no = 0;
int i;
// Creating socket file descriptor
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
{
perror("socket failed");
exit(EXIT_FAILURE);
}
// Forcefully attaching socket to the port 8080
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,
&opt, sizeof(opt)))
{
perror("setsockopt");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons( LISTENING_PORT );
// Forcefully attaching socket to the port 8080
if (bind(server_fd, (struct sockaddr *)&address,
sizeof(address))<0)
{
perror("bind failed");
exit(EXIT_FAILURE);
}
if (listen(server_fd, CLIENT_COUNT - 1) < 0)
{
perror("listen");
exit(EXIT_FAILURE);
}
while (1)
{
for (i=0; i < CLIENT_COUNT; i++)
{
/* Handle the accepted connection from client */
if (pthread_create(&thread_id[client_no] , NULL,
handle_new_conn, (void*) &server_fd) < 0)
{
perror("Couldn't create thread");
exit(EXIT_FAILURE);
}
client_no++;
}
client_no = 0;
for (i=0; i < CLIENT_COUNT; i++)
{
pthread_join(thread_id[client_no], NULL);
printf("Thread [%d] destroyed\n",
thread_id[client_no]);
client_no++;
}
/* Wait for the next interval to fetch the feed */
sleep(40);
}
return 0;
}
client.c
// Client side C/C++ program to demonstrate Socket programming
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#define SERVER_PORT 8080
void record_video()
{
/* Record video that has to be transmitted */
}
void handle_request(int sock)
{
char *hello = "Hello from client";
char * buffer[1024] = {0};
int valread;
printf("Client sock id: %d\n", sock);
sleep(2);
/* Connection to the server will be handled here */
send(sock , hello , strlen(hello) , 0 );
printf("Hello message sent\n");
valread = read( sock , buffer, 1024);
printf("%s\n",buffer );
close(sock);
}
int main(int argc, char const *argv[])
{
struct sockaddr_in address;
int sock = 0, valread;
struct sockaddr_in serv_addr;
char *hello = "Hello from client";
char buffer[1024] = {0};
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Socket creation error \n");
return -1;
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(SERVER_PORT);
// Convert IPv4 and IPv6 addresses from text to binary form
if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0)
{
printf("\nInvalid address/ Address not supported \n");
return -1;
}
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\nConnection Failed \n");
return -1;
}
record_video();
handle_request(sock);
return 0;
}
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.