I am trying to receive UDP data that is broadcast to network address 192.168.103.255 port 3000 by PlayCap (http://www.signal11.us/oss/playcap/). I'm having problems binding to this address and port. Here's my Java code:
public static void main(String[] args) {
try {
DatagramSocket s = new DatagramSocket();
InetSocketAddress address = new InetSocketAddress("192.168.103.255", 3000);
s.bind(address);
byte buffer[] = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
System.out.println("Waiting...");
s.receive(packet);
System.out.println("Received!");
} catch (Exception e) {
e.printStackTrace();
}
}
This returns the error:
java.net.SocketException: already bound
at java.net.DatagramSocket.bind(Unknown Source)
at runner.main(runner.java:12)
I have run the command "netstat -a -n", and neither address 192.168.103.255 nor port 3000 are listed anywhere in the output, so I don't think this port is already in use. In fact, I get this error for any address/port combination I try (including my static IP address).
I also wrote some C code to make a socket and bind to this address and port, but it also fails on the bind call. This code, however, will bind to ports on my static IP address (192.168.1.149). Here's that code:
#include <stdio.h>
#include <sys/types.h>
#include <winsock.h>
#include <unistd.h>
#define a1 192
#define a2 168
#define a3 103
#define a4 255
#define PORT 3000
int main() {
/* Open windows connection */
WSADATA w;
if (WSAStartup(0x0101, &w) != 0)
{
printf("Could not open Windows connection.\n");
exit(0);
}
/* Clear out server struct */
SOCKADDR_IN server;
memset((void *)&server, '\0', sizeof(struct sockaddr_in));
/* Set family and port */
server.sin_family = AF_INET;
server.sin_port = htons(PORT);
server.sin_addr.S_un.S_un_b.s_b1 = (unsigned char)a1;
server.sin_addr.S_un.S_un_b.s_b2 = (unsigned char)a2;
server.sin_addr.S_un.S_un_b.s_b3 = (unsigned char)a3;
server.sin_addr.S_un.S_un_b.s_b4 = (unsigned char)a4;
/* Open a datagram socket */
int sd = socket(AF_INET, SOCK_DGRAM, 0);
if (sd == INVALID_SOCKET)
{
printf("Could not create socket.\n");
WSACleanup();
exit(0);
}
/* Bind address to socket */
if (bind(sd, (struct sockaddr *)&server, sizeof(SOCKADDR_IN)) == -1)
{
printf("Could not bind name to socket.\n");
closesocket(sd);
WSACleanup();
exit(0);
}
/* Receive */
char data[1024];
printf("Waiting to receive...\n");
if (recv(sd, (char *)&data, (int)sizeof(data), 0))
{
printf("Error receiving data.\n");
closesocket(sd);
WSACleanup();
exit(0);
}
printf("Data: %s", data);
return 0;
}
I'm using a Windows 7 machine. I'm running the Java code in Eclipse. I'm compiling the C code with MinGW using the command:
gcc a.c -lws2_32
("a.c" is the file name).
While the Java code is more important, I would be happy to know where I'm going wrong in either of my code examples. Any suggestions are very much appreciated.
You would do this with the bind() function: int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); The first parameter is the file descriptor for the socket. The second is a pointer to a socket address structure which contains (for IPv4 or IPv6) the IP address and port to bind to.
Answer: Bind() function in socket programming is used to associate the socket with local address i.e. IP Address, port and address family. int bind(int sockfd,struct sockaddr *servaddr,int addrlength); There could be many combination of IP address and ports e.g. (10.17. 18.19, 6400), (10.17.
Once connected, a TCP socket can only send and receive to/from the remote machine. This means that you'll need one TCP socket for each client in your application. UDP is not connection-based, you can send and receive to/from anyone at any time with the same socket.
As far as I remember bind is not required for a UDP socket because a bind call is made for you by the stack.
Try this for your Java code instead:
public static void main(String[] args) {
try {
DatagramSocket s = new DatagramSocket(null);
InetSocketAddress address = new InetSocketAddress("192.168.103.255", 3000);
s.bind(address);
} catch (Exception e) {
e.printStackTrace();
}
}
Calling the no-arg constructor for a datagram socket will cause it to bind to a random, available port. Once bound, further attempts to (re)bind will throw a socket exception (with the error you were seeing). To 'defer' binding, you instead create the datagram socket in an unbound state (by passing a null in the constructor), then calling bind
later on.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With