I'm working on a cool project and I need to send 100,000 UDP Packets from a Server to a Client with a Packet-to-Packet Delay of 10ms. The Server is Debian Server with a public IP Address. The Client is an other Debian PC with LTE USB-Modem. The Client has no public IP Address and knows the public IP Address of my Server. My 4G/LTE Provider doesn't provide public IP Adresses to thier clients.
I need to build a stable UDP Socket Connection but I'm struggling keeping the socket connection alive.
Can somebody help me?
thx
best regards
/**** CLIENT ****/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#define PORT 20009
int main()
{
int sock;
int size;
int nbytes, flags;
int i;
int a = 0;
char * cp;
char buffer[] = "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789";
struct sockaddr_in target_pc, me;
sock = socket(PF_INET,SOCK_DGRAM,0);
if(sock < 0)
{
printf("socket error = %d\n", sock);
return -1;
}
target_pc.sin_family = PF_INET;
target_pc.sin_port = htons(PORT);
me.sin_family = PF_INET;
me.sin_port = htons(0);
me.sin_addr.s_addr = htonl(INADDR_ANY);
i = bind(sock, (struct sockaddr *) &me, sizeof(me));
if( i < 0)
{
printf("bind result: %d\n", i);
return -1;
}
nbytes = 200;
char str_addr[] = "155.55.25.25";
target_pc.sin_addr.s_addr = inet_addr(&str_addr[0]);
while(1)
{
nbytes = strlen(buffer);
flags = 0;
sendto(sock, (char *) buffer, nbytes,flags,(struct sockaddr *)&target_pc,sizeof(target_pc));
int addrlen = sizeof(target_pc);
size = recvfrom(sock, buffer, nbytes, flags, (struct sockaddr *)&target_pc,&addrlen);
if((size > 0) && (size < 200))
{
buffer[size] = '\0';
i = puts((char *) buffer);
}
printf("%i --- Size: %lu\n", a, sizeof(buffer));
a = a + 1;
}
return 0;
}
Below my Server Code:
/*** SERVER ***/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#define PORT 20009
void SleepMs(int ms)
{
usleep(ms*1000); //convert to microseconds
return;
}
int main()
{
int sock;
int size;
int nbytes, flags;
socklen_t addrlen;
int i;
char buffer[100];
char buffer2[] = "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\0";
struct sockaddr_in server;
struct sockaddr_in from;
sock = socket(AF_INET,SOCK_DGRAM,0);
if(sock < 0)
{
printf("socket error = %d\n", sock);
return -1;
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons(PORT);
i = bind(sock, (struct sockaddr *) &server, sizeof(server));
if( i < 0){
printf("bind result: %d\n", i);
return -1;
}
else{
printf("Simple UDP server is ready!\n");
}
nbytes = 200;
flags = 0;
while(1)
{
addrlen = sizeof(from);
size = recvfrom(sock, buffer, nbytes, flags, (struct sockaddr *)&from, &addrlen);
if((size > 0) && (size < 200))
{
buffer[size] = '\0';
i = puts((char *) buffer);
}
printf("\n");
sock = socket(PF_INET,SOCK_DGRAM,0);
if(sock < 0)
{
printf("socket error = %d\n", sock);
return -1;
}
sendto(sock, buffer2, nbytes, flags, (struct sockaddr *)&from,addrlen);
SleepMs(10); // Packet-to-Packet Delay Time
}
return 0;
}
You can have the connection using IP of the server in this case 192.168.1.2
server.sin_addr.s_addr = inet_addr("192.168.1.2");
using this in both codes
Related
The server receives messages from the client, but when sending back to the client through 3 channels, the sctp_recvmsg function returns -1. Sometimes when I run it works, but it happens every other time. Guys help me figure it out!
The server takes up a free port and displays it for connecting to clients. After that it listens on the socket and waits for a connection from the client. When connected, a separate stream is created which is engaged in customer service. After receiving the message, the stream sends back the received message via three channels to the client.
Server
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/sctp.h>
#include <errno.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <iostream>
#include <thread>
#include <vector>
using namespace std;
vector<thread> threadPool;
void multichatThread(int newsock, int flags)
{
char buffer[512];
printf("Новый клиент!\n");
struct sctp_sndrcvinfo sndrcvinfo; // информация о пересылке
if (sctp_recvmsg(newsock, (void *)buffer, sizeof(buffer), (struct sockaddr *)NULL, 0, &sndrcvinfo, &flags) == -1)
{ // принимаем сообщение от клиента
printf("Error sctp_recvmsg!\n");
return;
}
printf("%s\n", buffer);
int i;
for (i = 0; i < 3; i++)
{ // по всем 3-м потокам отправляем информацию
if (sctp_sendmsg(newsock, (void *)buffer, (size_t)strlen(buffer), NULL, 0, 0, 0, i, 0, 0) == -1)
{ // отправляем клиенту сообщение
int ec = errno;
printf("Error sctp_recvmsg %d - %s!\n", ec, strerror(ec));
return;
}
}
close(newsock); // закрываем связь с клиентом
}
void createServer()
{
struct sockaddr_in server, client;
int sock;
// создание сокета
if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP)) == -1)
{
printf("Error create socket!\n");
return;
}
// структура для сервера
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY); // локальный адрес
server.sin_port = htons(0); // порт сервера
// связка
if (bind(sock, (struct sockaddr *)&server, sizeof(server)) == -1)
{
printf("Error bind!\n");
return;
}
// настройка канала
struct sctp_initmsg initmsg;
initmsg.sinit_num_ostreams = 3; // входные потоки
initmsg.sinit_max_instreams = 3; // выходные потоки
initmsg.sinit_max_attempts = 2; // максимальное количество попыток
setsockopt(sock, IPPROTO_SCTP, SCTP_INITMSG, &initmsg, sizeof(initmsg));
// объявляем очередь
if (listen(sock, 5) == -1)
{
printf("Error listen!\n");
return;
}
struct sockaddr_in sin;
socklen_t len = sizeof(sin);
if (getsockname(sock, (struct sockaddr *)&sin, &len) == -1)
perror("getsockname");
else
{
printf("Сервер создан!\n");
printf("IP: %s\n", inet_ntoa(sin.sin_addr));
printf("Port: %d\n", ntohs(sin.sin_port));
}
int newsock;
int clnlen = sizeof(client), flags;
while (true)
{
if ((newsock = accept(sock, (struct sockaddr *)&client, (socklen_t *)&clnlen)) == -1)
{
printf("Error accept!\n");
return;
}
thread chatThread(multichatThread, newsock, flags);
chatThread.detach();
threadPool.push_back(move(chatThread));
}
close(sock); // закрываем сокет сервера
}
int main()
{
createServer();
return 0;
}
The client receives the port and connects to the server. Then it sends a message to the server and waits for a response from the server through three channels.
Client
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/sctp.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <netdb.h>
#include <unistd.h>
#include <iostream>
using namespace std;
void connectServer(string ip, uint16_t port)
{
// настройка структуры для сервера
struct sockaddr_in server;
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons(port);
// создаем сокет
int sock;
if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP)) == -1)
{
printf("Error create!\n");
return;
}
// настройка канала
struct sctp_initmsg initmsg;
memset(&initmsg, 0, sizeof(initmsg));
initmsg.sinit_num_ostreams = 3; // выходные потоки
initmsg.sinit_max_instreams = 3; // входные потоки
initmsg.sinit_max_attempts = 2; // количество попыток
setsockopt(sock, IPPROTO_SCTP, SCTP_INITMSG, &initmsg, sizeof(initmsg));
struct sockaddr_in sin;
socklen_t len = sizeof(sin);
printf("Данные о сокете!\n");
printf("IP: %s\n", inet_ntoa(server.sin_addr));
printf("Port: %d\n", ntohs(server.sin_port));
// соединяемся с сервером
if (connect(sock, (struct sockaddr *)&server, sizeof(server)) == -1)
{
printf("Error connect!\n");
return;
}
// отправка и прием сообщения
char buf[512] = "Hello!";
if (sctp_sendmsg(sock, (void *)buf, (size_t)strlen(buf), NULL, 0, 0, 0, 1 /* номер потока */, 0, 0) == -1)
{
printf("Ошибка отправки пакета к серверу!\n");
return;
}
struct sctp_sndrcvinfo sndrcvinfo;
int i, flags;
char buff[512];
for (i = 0; i < 3; i++)
{ // по 3-м каналам принимаем сообщения
bzero((void *)&buff, sizeof(buff));
if (sctp_recvmsg(sock, (void *)buff, sizeof(buff), (struct sockaddr *)NULL, 0, &sndrcvinfo, &flags) == -1)
{
printf("Ошибка отправки пакета от сервера!\n");
return;
}
printf("Сервер: %s\n", buff);
}
close(sock);
}
int main()
{
string ip;
uint16_t port;
cout << "Введите IP:";
cin >> ip;
cout << "Введите PORT:";
cin >> port;
connectServer(ip, port);
return 0;
}
First, check the errno value on error - it may help.
if (sctp_recvmsg(newsock, (void *)buffer, sizeof(buffer), (struct sockaddr *)NULL, 0, &sndrcvinfo, &flags) == -1)
{
int ec = errno;
printf("Error sctp_recvmsg %d - %s!\n", ec, strerror(ec));
return;
}
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'm making a client-server program in C using threads.
I've got this problem: on the server, on thread #1 (number_one), function "read" works fine. But when I create another thread #2 (number_two), on this one something goes wrong. Parameters are passed in the right way (I think).
-->thread number_one
...
char message[256];
int new_connection=accept(master_sock,NULL,NULL);
pthread_t temp
if(pthread_create(&temp , NULL , number_two , (void*) &new_connection))
{
perror("pthread_create failed");
exit(-2);
}
else
{
puts("number_two created");
if(read(new_connection, message, 256) > 0)
printf("Message from client is %s", message);
}
if(pthread_detach(temp))
{
perror("detach failed");
exit(-3);
}
...
---> thread number_two
void *number_two(void *sock_desc)
{
int sock = *(int*)sock_desc;
int read_size;
char client_message[2000];
read_size=read(sock, client_message, 256);
client_message[read_size]='\0';
return 0;
}
In "number_one", read waits an input from the client, and then it sets correctly the buffer "message".
In "number_two", read does not wait the client and does not set the buffer "client_message".
Thank you.
Please try my code? it works, I think it is the same with your code.
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <pthread.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <netdb.h>
#define INVALID_SOCKET_FD (-1)
int create_tcp_server_socket(unsigned short port, bool bind_local, int backlog,
char *caller_name)
{
int socket_fd = INVALID_SOCKET_FD;
struct sockaddr_storage server_addr;
unsigned int yes = 1;
// just try ipv4
if (socket_fd < 0 && (socket_fd = socket(PF_INET, SOCK_STREAM, 0)) >= 0) {
struct sockaddr_in *s4 = (struct sockaddr_in *)&server_addr;
setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
memset(&server_addr, 0, sizeof(server_addr));
s4->sin_family = AF_INET;
s4->sin_port = htons(port);
if (bind_local)
s4->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
else
s4->sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(socket_fd, (struct sockaddr *)&server_addr,
sizeof(server_addr)) < 0) {
close(socket_fd);
printf("Server: Failed to bind ipv4 server socket.\n");
return INVALID_SOCKET_FD;
}
}
else if (socket_fd < 0) {
printf("Server: Failed to create server socket.\n");
return INVALID_SOCKET_FD;
}
if (listen(socket_fd, backlog) < 0) {
close(socket_fd);
printf("Server: Failed to set listen.\n");
return INVALID_SOCKET_FD;
}
return socket_fd;
}
pthread_t temp;
void *number_two(void *sock)
{
char buf[1024];
int fd = *(int *)sock;
int nread = read(fd, buf, 1024);
write(STDOUT_FILENO, buf, nread);
return NULL;
}
int main()
{
pid_t pid;
if ((pid = fork()) < 0) {
}
else if (pid > 0) { // parent, server
char buf[1024];
int fd = create_tcp_server_socket(8787, false, 10, "zz");
int new_fd = accept(fd, NULL, 0);
pthread_create(&temp, NULL, number_two, (void *)&new_fd);
}
else { // child, client
uint32_t ip;
struct hostent *hp = gethostbyname("localhost");
memcpy(&ip, hp->h_addr_list[0], hp->h_length);
struct sockaddr_in server_addr;
memset((char *)&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = ip;
server_addr.sin_port = htons(8787);
int fd = socket(AF_INET, SOCK_STREAM, 0);
connect(fd, (struct sockaddr *)&server_addr, sizeof(server_addr));
write(fd, "abcd", 4);
}
pause();
return 0;
}
I posted my code here: communication between windows client and linux server?
I am performing communication between client and server.I know that udp is a connectionless program nothing but it wont send any response back to the client. If i want to send a response back to the client then what should i do ??
I solved all my errors in the above link but I got a doubt w.r.t sending a response back to the client. so i am re posting here.
This is the code I wrote when I start learning socket programming, hope it helps:
server
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
struct sockaddr_in server;
struct sockaddr_in client;
int socket_fd;
int ret;
char buf[255];
int len = sizeof(struct sockaddr_in);
socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
if(socket_fd < 0)
{
printf("socket error\n");
return -1;
}
server.sin_family = AF_INET;
server.sin_port = htons(5900);
server.sin_addr.s_addr = htonl(INADDR_ANY);
ret = bind(socket_fd, (struct sockaddr *)&server, sizeof(struct sockaddr));
if(ret)
{
printf("error while binding\n");
return -1;
}
ret = recvfrom(socket_fd, buf, sizeof(buf), 0, (struct sockaddr *)&client, &len);
if(ret < 0)
{
printf("reciving error\n");
}
printf("recving data from %s: %s\n", inet_ntoa(client.sin_addr), buf);
snprintf(buf, sizeof(buf), "server:");
ret = sendto(socket_fd, buf, sizeof(buf), 0, (struct sockaddr *)&client, sizeof(client));
if(ret < 0)
{
printf("send error\n");
return -1;
}
close(socket_fd);
return 0;
}
client
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
int socket_fd;
struct sockaddr_in server;
int ret;
char buf[255] = "send to server";
int len = sizeof(struct sockaddr_in);
socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
if(socket_fd < 0)
{
printf("socket error\n");
}
server.sin_family = AF_INET;
server.sin_port = htons(5900);
server.sin_addr.s_addr = inet_addr("127.0.0.1");
ret = sendto(socket_fd, buf, sizeof(buf), 0, (struct sockaddr *)&server, sizeof(server));
if(ret < 0)
{
printf("sendto error\n");
return -1;
}
ret = recvfrom(socket_fd, buf, sizeof(buf), 0, (struct sockaddr *)&server, &len);
if(ret < 0)
{
printf("error recv from\n");
return -1;
}
printf("recving from server:%s: %s\n", inet_ntoa(server.sin_addr), buf);
close(socket_fd);
}
Read the code above and you will find the answer to your question
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.