I have created a very simple server program to accept a connection send "Hello World" back to client.I connected to server (localhost) using telnet and it works fine.Now I want to run it over internet and its not working. I tried binding it to my public IP address(search it on google) and it doesn't work.`server_socket=socket(AF_INET,SOCK_STREAM ,0);
serverAddr.sin_family = AF_INET;
serverAddr.sin_port= htons(7892);
serverAddr.sin_addr.s_addr = inet_addr("192.168.43.241");//htonl(INADDR_ANY);//INADDR_ANY;//inet_addr("157.48.97.106");
memset(serverAddr.sin_zero,'\0',sizeof serverAddr.sin_zero);
bind(server_socket, (struct sockaddr *)&serverAddr,sizeof(serverAddr) );
if(listen(server_socket,5)==0)
printf("listening\n");
addr_size=sizeof client_addr;
printf("IP address is: %s\n", inet_ntoa(serverAddr.sin_addr));
while(1)
{
client_socket= accept( server_socket,(struct sockaddr *)&client_addr,&addr_size);
printf("Waiting\n");
printf("client_socket %d\n",client_socket);
int pid=fork();
if(pid>0)
{
printf("PID:%d\n",pid);
dup2(0,client_socket);
}
else
{
dup2(client_socket,0);
printf("%d %d\n",pid,client_socket);
send(client_socket,buffer,strlen(buffer),0);
printf("Message Sent\n");
shutdown(client_socket,0);
close(client_socket);
perror("CLOSE");
printf("Connection Closed\n");
exit(0);
}
}`
In principal you can bind to 0.0.0.0 (which should be the same as the INADDR_ANY that you have in the comment) to listen on all IPv4 addresses. This means you will be able to accept loopback connections as well as connections on all network cards (and thereby from the outside). This should work for you (assuming the remaining program works reliably on loopback).
If you can't connect from outside of the PC on the same network you most likely have a firewall configuration issue. Some OSes by default block incoming connections from the outside if there's no explicit firewall rule that allows it.
If you want to connect from the internet to the PC and you are connected through a router with NAT you also have to configure the router to forward the connection correctly.
Related
I have to send a file to the local server so I use the httpClient and try to use the post with the host: http://127.0.0.1:5000/show-version, In the serial monitor, but it doesn't work, again the ESP is in access point mode
void SendVersion (){
client.begin(HOST);
client.addHeader("Content-Type", "text/plain");
int response = client.POST(version);
if(response>0){
String response = client.getString(); //Get the response to the request
Serial.println(response); //Print return code
Serial.println(response); //Print request answer
}else{
Serial.print("Error on sending POST: ");
Serial.println(response);
}
client.end();
}
127.0.0.1 is a special IP address which means "this computer or device". When you use it on the ESP32 it means the ESP32, not the server you're trying to connect to. It's also known as localhost - again, shorthand for the computer or device the software is running on. It does not identify an external computer.
You need to use the actual IP address of the server you're trying to connect to. How you'll find that depends on the OS the server is running - if you don't know how to do it, use Google to find out.
And of course, if the ESP32 is in AP mode then the server it's trying to talk to needs to be connected to the ESP32's wifi network in order for the ESP32 to be able to talk to it.
On an STM32H753 I run an example tcp echo client from STM32Cube_FW_H7.
The board however has three network interfaces with different IP addresses, all serviced by LwIP (1x LAN8742 + 2x KSZ8851).
Using ping I verified the correct ports are responding, by disconnecting others.
For example IP 192.168.0.101 is assigned to port 1, IP 192.168.0.102 is assigned to port 2, and IP 192.168.0.103 is assigned to port 3.
In ethernetif*.c, the three interfaces got names "st", "M1", and "M2".
All works fine, but the tcp_echoclient_connect function always selects the 3rd port as the local port. How can I tell LwIP to select for example the 1st or 2nd port?
The tcp_echoclient_connect function calls
/* connect to destination address/port */
tcp_connect(echoclient_pcb, &DestIPaddr, DEST_PORT, tcp_echoclient_connected);
It then selects the 3rd interface (and IP address).
In tcp.c, the function tcp_connect shows how to obtain a suitable interface:
/* check if we have a route to the remote host */
if (ip_addr_isany(&pcb->local_ip)) {
/* no local IP address set, yet. */
struct netif *netif;
const ip_addr_t *local_ip;
ip_route_get_local_ip(&pcb->local_ip, &pcb->remote_ip, netif, local_ip);
if ((netif == NULL) || (local_ip == NULL)) {
/* Don't even try to send a SYN packet if we have no route
since that will fail. */
return ERR_RTE;
}
/* Use the address as local address of the pcb. */
ip_addr_copy(pcb->local_ip, *local_ip);
}
So I'd like to specify a particular netif (interface).
How can I do that?
When I run the tcp echo server, it uses the right interface.
I can send a message to the corresponding port and it responds back. The wrong port does not respond.
My source
https://github.com/bkht/LAN8742A_KSZ8851SNL_LwIP
Note:
ip_route_get_local_ip calls ip_route, which returns the first netif that matches the netmask. It's the function ip4_route in ip4.c.
For now, as I could not find another way to select a partiular netif, I created a few functions to select the desired netif by name:
In ip4.c
struct netif *ip4_route_by_name(const char *name, const ip4_addr_t *dest)
In tcp.c
err_t tcp_connect_by_name(const char *name, struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port, tcp_connected_fn connected)
In the tcp_echoclient server, I specify a netif name when creating a connection:
/* from a specified netif connect to destination address/port */
tcp_connect_by_name("m1", echoclient_pcb, &DestIPaddr, DEST_PORT, tcp_echoclient_connected);
But maybe the functionality existed already to specify a netif which matches the netif name, MAC address, or IP address?
I am running an application on my microcontroller(MSP432), which writes data to an Ethernet cable to send it over to PC.
I am using Packet sender to view the data received on the port(502) on PC from MC.
Data received on PC
As we can see in the above picture, the port numbers of MC are increment for every packet sent.
What will happen when it reaches to the maximum number?
Will it restart at some other port number and proceed with the process or will it stop?
Edit1: Modbus protocol library used from http://myarduinoprojects.com/modbus.html
Edit2:
Making a call to this function everytime i have a new data to send through MODBUS. Mb.Req(MB_FC_WRITE_MULTIPLE_REGISTERS, 0,11,0);
if (MbmClient.connect(ServerIp,502)) {
digitalWrite(GREEN_LED, HIGH);
#if DEBUG
//Serial.println("connected with modbus slave");
// Serial.print("Master : ");
for(int i=0;i<MbmByteArray[5]+6;i++) {
if(MbmByteArray[i] < 16){
//Serial.print("0");
}
//Serial.print(MbmByteArray[i],HEX);
if (i != MbmByteArray[5]+5) {
//Serial.print(".");
} else {
//Serial.println();
}
}
#endif
MbmClient.write(MbmByteArray,13+(Count*2));
MbmCounter = 0;
MbmByteArray[7] = 0;
MbmPos = Pos;
MbmBitCount = Count;
*state= true;
MbmClient.stop();
delay(100);
digitalWrite(GREEN_LED, LOW);
} else {
*state= false;
MbmClient.stop();
}
It seems you are using this Modbus example
I have never worked with that but I suppose that because the destination port in the code is the same you have in your sniffing image: 502
Probably you are repeatedly calling this method:
void MgsModbus::Req(MB_FC FC, word Ref, word Count, word Pos)
Inside this method you can see this line:
if (MbmClient.connect(ServerIp,502)) {
...
So every time you call that function a new connection is open. When you open a connection through a socket, the operating system or the network stack needs to select a source port and IP address from where the TCP message is sent.
This is why you see always a new source port and that port is increasing. This is what is called an ephemeral port. How the source port is selected by the TCP stack you are using is implementation dependent, though it's very common to begin with some port and every time a connection is open, it selects the next available port.
If the stack is well programmed, most probably your TCP stack will wrap around and begin with some specific port from 1024 up (First 1024 ports are restricted). The code I saw seems to close the port with this function:
MbmClient.stop()
You need to check ports, after being used, are closed. Otherwise, at some point you will run out of available ports (resource leak).
If you want your socket bound to a specific source port, you need to use a function similar to Linux socket bind
Now, a wiser way is to use all the time the same connection. You may need to modify that example.
I'm completely new at using the QtNetwork for connecting computers.
Right now all I want is to see an attempt at a connection. So I create a GUI application and on the mainwindow.cpp I write these two functions as slots for two buttons:
void MainWindow::on_pbTalk_clicked(){
QString IP = ui->leIP->text();
ui->pteLog->appendPlainText("Now Talking to IP: " + IP);
talker = new Talker();
talker->connectToHost(IP,25000);
}
void MainWindow::on_pbListen_clicked(){
ui->pteLog->appendPlainText("Now listening on any port, I think");
listener = new Listener(this);
if (!connect(listener, SIGNAL(newConnection()), this, SLOT(on_newConnections()))){
ui->pteLog->appendPlainText("The connection of slot and signal failed!");
}
}
Now Talker is essentially a QTcpSocket there is nothing reimplemented just yet.
Listener is a QTcpServer with the following code con Listener.cpp:
Listener::Listener(QObject *parent) :
QTcpServer(parent)
{
qDebug() << "Listening on any port";
listen(QHostAddress::Any);
}
void Listener::incomingConnection(int socketDescriptor){
qDebug() << "New connection: " << socketDescriptor;
}
So I run two instances of the same program. One is in my machine. I run the program and push the Listen button (IP 10.255.255.101).
The second instance is run in a virtual machine (IP 10.255.255.215) where I run the program and push the Talk button. This, as I understand should attempt to open a connection to IP (which is 10.255.255.101) at port 25000 and I should get a "New connection" message in the console. However no such message appears. And since this is not working, I'm not moving on.
Can any one tell me what I might be doing wrong?
Check the documenation of QTcpServer::listen - it says:
Tells the server to listen for incoming connections on address address
and port port. If port is 0, a port is chosen automatically. If
address is QHostAddress::Any, the server will listen on all network
interfaces.
QHostAddress::Any means that you are listening on all network interfaces, not ports. (For example, if you want to have a local server only, you could use QHostAddress::LocalHost - check QHostAddress::SpecialAddress for more like that.
If you want to set the port manually, you have to call:
listen(QHostAddress::Any, 25000);
If not, you can get the automatically chosen port by calling
quint16 port = serverPort();
The "listening on any port" idiom isn't available for your use; it's not how UDP and TCP were meant to be used. Most likely you shouldn't be designing your communications that way. Use a dedicated port.
If you want to build a packet sniffer, you'll have to use the platform-specific mechanisms designed for that. There are libraries that help you with that task, the most notable would be WinPcap on Windows and cross-platform libpcap from the TcpDump project.
I have a question about Qt & network sockets. If I have a computer with multiple IP-Adresses in different networks, how do I open an udp socket for a multicastgroup on a specific network-adapter/ip adress.
eg: ip 192.168.2.1 and 172.20.0.1 and I want to create a socket that receives packets from the multicast group 228.5.6.7 on the 172.20.0.1 network adapter.
You should set that in imr_interface as shown below: (probably it's set to INADDR_ANY now)
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = inet_addr("228.5.6.7");
mreq.imr_interface.s_addr = inet_addr("172.20.0.1");// <---- right here
...
QSocketDevice* sdev = new QSocketDevice(QSocketDevice::Datagram);
...
setsockopt(sdev->socket(), IPPROTO_IP, IP_ADD_MEMBERSHIP,(const char *)&mreq, sizeof(struct ip_mreq));
...
If it's a listening socket, you can use bind to IP address to bind it to a specific IP address to listen on.
If it's a client socket, the OS manage the right interface to create it on to reach that IP address as per routing table rules.