This is my code
#include "basic.h"
#include "bp_socket.h"
int setup_tcp(char *port)
{
struct sockaddr_in server_addr;
in_port_t server_port;
int sock;
int retval; //return value
if ((server_port = atoi(port)) < 0)
{
server_port = (in_port_t)DEFAULT_PORT;
fprintf(stderr, "Error port: %d in line %d\n", (int)server_port, __LINE__);
//fprintf(stderr, "Use default port: %d\n", DEFAULT_PORT);
}
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock < 0)
{
return sock;
}
retval = listen(sock, 40);
if (retval < 0)
{
return retval;
}
memset(&server_addr, 0, sizeof(struct sockaddr_in));
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(server_port);
server_addr.sin_family = AF_INET;
retval = bind(sock, (struct sockaddr*)&server_addr, sizeof(server_addr));
if (retval < 0)
{
perror("bind");
return retval;
}
return sock;
}
int main()
{
printf("%d\n", setup_tcp("4558"));
perror("");
return 0;
}
I debug my code, then I found bind() return -1
I google it and read man page, but I couldn't found my answer.
function setup_tcp is create socket, and bind with address.
then return a socket or errno value.
How to solve it. I had read my code for many times.
Thank you!
You should move the listen after the bind.
bind returns an error if the socket is already bound, and listen on an unbound socket automatically binds it to a random port number.
Related
It's been an hour since I started looking for THE error. I just started C sockets. The program exits with code -1 after printing "Error 1 connection error". The server in online, it's a netcat server. Where did I messed up ?
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#define HOST "127.0.0.1"
#define PORT 4444
int main(int argc, const char *argv[])
{
struct sockaddr_in addr;
int sock = 0;
int ret;
struct sockaddr_in server_addr;
char *msg = "Hello world !\n";
char inBuffer[1024] = { 0 };
if (sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) < 0)
{
printf("Error %d socket creating.\n", sock);
exit(-1);
}
else
{
memset(&server_addr, '0', sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
if (ret = inet_pton(AF_INET, HOST, &server_addr.sin_addr) <= 0)
{
printf("Error %d unsuported address: %d\n", ret);
exit(-2);
}
else
{
if (ret = connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
{
printf("Error %d connection error\n", ret);
exit(-3);
}
else
{
send(sock, msg, strlen(msg), 0);
read(sock, inBuffer, 1024);
printf("%s\n", inBuffer);
return 0;
}
}
}
}
Due to operator precedence, the expression
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) < 0
is actually equal to
sock = (socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) < 0)
That is, you assign the result of the comparison socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) < 0 to the variable sock. The result of that comparison will always be either 0 (for false) or 1 (for true). Neither 0 nor 1 should be a valid socket.
You need to explicitly add parentheses for the assignment:
(sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0
The same needs to be done for the connect call and the comparison there.
There is my function. I pass argument port as 80 and I always can not bind socket.
int create_socket(int port)
{
int sock;
struct sockaddr_in name;
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
fprintf(stderr, "Can not create socket\n");
return -1;
}
//Assigning a name to the socket
name.sin_family = AF_INET;
name.sin_port = htons((unsigned short)port);
name.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(sock, (const struct sockaddr *) &name, sizeof(name)) == -1) {
fprintf(stderr, "Can not bind socket\n");
return -1;
}
return sock;
}
Typically port number less than 1024 are used by well known network servers and in linux, root privilege is required to open these ports.
80 is HTTP port and so your program requires root privilege.
Iv'e tried to run server client between 2 computers in my local network in my house.
I failed with error 10049 in the client side. I thought it was something with firewall so I've tried to run it my computer(with threads), but still the same issue.
I'm failing at function "connect" with my output:
"error - connect failed. sockfd is 188, errno is 34, WSA is 10049"
here's my code.
app.c:
#include "client.h"
#include "server.h"
int main()
{
DWORD dwThreadID1, dwThreadID2;
CreateThread(
NULL, // default security attributes
0, // default stack size
(LPTHREAD_START_ROUTINE) apserver,
NULL, // no thread function arguments
0, // default creation flags
&dwThreadID1); // receive thread identifier
CreateThread(
NULL, // default security attributes
0, // default stack size
(LPTHREAD_START_ROUTINE) apClient,
NULL, // no thread function arguments
0, // default creation flags
&dwThreadID2); // receive thread identifier
while(1)
{}
return 0;
}
server.c:
#include "server.h"
int socketBind(int sockfd, int port){
struct sockaddr_in serv_addr;
ZeroMemory((char*) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(port);
if ( bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0 ){
// we can check errno for exact ERROR
printf("bind failed with errno %d\n",errno);fflush(NULL);
return ERROR;
}
if ( listen(sockfd, 100) == -1 ){
return ERROR;
}
return 1;
}
DWORD WINAPI apserver(LPVOID lpParam)
{
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2,2), &wsaData) == SOCKET_ERROR) {
printf ("Error initialising WSA.\n");
return -1;
}
int sockfd; // server's listening socket's descriptor id
int port = 4997;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
while ( sockfd < 0 ){ // ERROR
printf("Listener socket creation failed with:%d, errno is %d\n",sockfd,errno);fflush(NULL);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
}
if ( socketBind(sockfd, port) == ERROR ){
printf("Socket bind failed with errno=%d\n",errno);fflush(NULL);
close(sockfd);
return ERROR;
}
printf("Starting to listen to other USERS!\n");fflush(NULL);
struct sockaddr_in cli_addr;
int clilen = sizeof(cli_addr); // length of address
// accept() returns the socket that will be used for Control Connection with the accepted client
printf("*************Waiting for other USERS************\n");fflush(NULL);
int newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen);
int readLength;
char command[(128+1)];
while(1)
{
ZeroMemory(command, sizeof(command));
readLength = read(newsockfd, command, 128+1);
if(readLength == 0)
{
continue;
}
if(readLength > 0)
{
printf(" here should be API's func to command %s", command);fflush(NULL);
}
else
{
close(sockfd);
close(newsockfd);
WSACleanup();
printf("Read failed with errno:%d\n",errno);fflush(NULL);
return ERROR;
}
}
close(sockfd);
close(newsockfd);
WSACleanup();
return 1;
}
client.c:
#include "client.h"
int verifyWrite(int sockfd, char* command){
int size = strlen(command);
int i=0, x=0;
for(i=0;i<size;){
x = write(sockfd, command, size);
if(x < 0){
return ERROR;
}
if(x >= 0) {
i += x;
}
}
return 0;
}
int sendToAll(char* message, int sockfd)
{
if ( verifyWrite(sockfd, message) < 0 )
{
printf("error while sending message\n");fflush(NULL);
}
return 0;
}
DWORD WINAPI apClient(LPVOID lpParam)
{
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2,2), &wsaData) == SOCKET_ERROR) {
printf ("Error initialising WSA.\n");
return -1;
}
int port,sockfd;
struct sockaddr_in serv_addr;
sockfd = socket(AF_INET, SOCK_STREAM, 0); //creating control connection
while(sockfd < 0){
printf("error - sockfd = %d\n",sockfd);fflush(NULL);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
}
port = 4997;
serv_addr.sin_addr.s_addr = inet_addr("192.168.x.x");
ZeroMemory((char*)&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(port);
while(connect(sockfd,(struct sockaddr*)&serv_addr,sizeof(serv_addr)) < 0){
printf("error - connect failed. sockfd is %d, errno is %d, WSA is %d\n",sockfd,errno,WSAGetLastError());fflush(NULL);
}
printf("\n opened connection to %s\n", "192.168.x.x");fflush(NULL);
int i = 0;
while(i< 6)
{
sendToAll("just a message", sockfd);
i++;
}
WSACleanup();
return 0;
}
Windows socket error 10049 is WSAEADDRNOTAVAIL, and if you read about it you will see that
connect, ... when the remote address or port is not valid for a remote computer (for example, address or port 0).
The reason is very simple:
serv_addr.sin_addr.s_addr = inet_addr("192.168.x.x");
ZeroMemory((char*)&serv_addr, sizeof(serv_addr));
You clear the structure after you set the address you want to connect to.
I have writter code snippet for UDP Client and server. I am using same port for sending and receiving. My problem is that there are many messages drops at client side, so can someone help me to optimize my code, here is my code for UDP client:
#define SERVERIP "192.168.170.155"
#define SERVERPORT 5000
#define DEVICE_SEND_PORT 5000
#define DEVICE_RECEIVE_PORT 5000
#define BUFFERSIZE 2048
/**For socket file descriptor identification*/
#define S1READY 0x01
int m_SendSocketId;
int m_ReceiveSocketId;
int msgcount;
int socketbuffsize = 1*1024*1024;
/**
* FUNCTION NAME : waitToRead
* Implementation of select and non-blocking socket mechanism
* #param socket Socket that needs to be in select and non blocking mode
* #return Returnd the file descriptors which, returned by select function
*/
int waitToRead(int socket)
{
fd_set fds;
struct timeval timeout;
int rc; // number of file descriptor returned
int result; // result
int fd; // file descriptor
fd=fcntl(socket,F_GETFL,0);
fcntl(socket,F_SETFL,fd | O_NONBLOCK);
// Set time limit.
timeout.tv_sec = 1;
timeout.tv_usec = 0;
// Create a descriptor containing our sockets.
FD_ZERO(&fds);
FD_SET(socket, &fds);
rc = select(sizeof(fds)*8, &fds, NULL, NULL, &timeout);
if (rc==-1)
{
printf("[%s:%d#%s] Select Failed\n",__FILE__, __LINE__,__func__);
return -1;
}
result = 0;
if (rc > 0)
{
if (FD_ISSET(socket, &fds))
result |= S1READY;
}
return result;
}
/**
* FUNCTION NAME : receiveMessage
* This function opens particular port that is defined in the
* Configuration file, and listens on that port.
* #return if there'll be any issue in listening, then it will return
* false otherwise it will return true.
*/
bool receiveMessage()
{
struct sockaddr_in serverAddr; //Information about the Device UDP Server
struct sockaddr_in client_addr; // Information about Qgate Server
char buffer[BUFFERSIZE]; // Buffer to store incoming message
int addr_len; // to store client address length
int serverlen; // to store server address length
int sockResult; // to store result given by waitToRead
int optval = 1;
int receivedByte = 0;
//Open a datagram Socket
if((m_ReceiveSocketId = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
printf("[%s:%d#%s] UDP Client - socket() error\n",__FILE__, __LINE__,__func__);
return false;
}
//Configure Server Address.
//set family and port
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(DEVICE_RECEIVE_PORT);
setsockopt(m_ReceiveSocketId, SOL_SOCKET,SO_REUSEADDR, &optval, sizeof(optval));
/*if (setsockopt(m_ReceiveSocketId, SOL_SOCKET, SO_RCVBUF, &socketbuffsize, sizeof(socketbuffsize)) == -1)
{
printf("Recieve Socket memory Allocation fail\n");
}*/
if((serverAddr.sin_addr.s_addr = INADDR_ANY) == (unsigned long)INADDR_NONE)
{
printf("[%s:%d#%s] Host Not found(%d)\n",__FILE__, __LINE__,__func__,h_errno);
close(m_ReceiveSocketId); // close the socket
return false;
}
if (bind(m_ReceiveSocketId, (struct sockaddr *) &serverAddr,sizeof(struct sockaddr_in)) < 0 )
{
printf("[%s:%d#%s] UDP Client- Socket Bind error=%s\n",__FILE__, __LINE__,__func__,strerror(errno));
close(m_ReceiveSocketId); // close the socket
return false;
}
serverlen = (int )sizeof(serverAddr);
addr_len = sizeof(struct sockaddr);
// Loop and listen for incoming message
while(1)
{
//wait at select to, read
sockResult = waitToRead(m_ReceiveSocketId);
if(sockResult == S1READY)
{
receivedByte = read(m_ReceiveSocketId,buffer,BUFFERSIZE);
buffer[receivedByte] = '\0';
if(receivedByte == -1)
{
printf("[%s:%d#%s] UDP Client - receive error", __FILE__,__LINE__,__func__);
close(m_ReceiveSocketId);
return false;
}
else if(receivedByte > 0)
{
//printf("[%s:%d#%s] received message = %d bytes\n",__FILE__,__LINE__,__func__,(int)strlen(buffer));
printf("count: %d, buffer %s \n", msgcount++, buffer);
}
}
memset(buffer, 0, BUFFERSIZE);
fflush(stdout);
}
close(m_ReceiveSocketId); // close the socket
printf("[%s:%d#%s] Recieve socket closed:%s\n",
__FILE__, __LINE__,__func__, strerror(errno));
return true;
}
bool sendMessage(char *message)
{
struct sockaddr_in serverAddr; //Information about the server
struct sockaddr_in deviceAddr; //Device UDP Client Address for sending message
int optval = 1;
//Open a datagram Socket
if((m_SendSocketId = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
printf("[%s:%d#%s] UDP Client - socket() error\n",__FILE__, __LINE__,__func__);
return false;
}
// Clear out the device struct
memset(&deviceAddr, 0x00, sizeof(struct sockaddr_in));
deviceAddr.sin_family = AF_INET;
deviceAddr.sin_port = htons(DEVICE_SEND_PORT);
setsockopt(m_SendSocketId, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
/*if (setsockopt(m_SendSocketId, SOL_SOCKET, SO_SNDBUF, &socketbuffsize, sizeof(socketbuffsize)) == -1)
{
printf("send Socket memory Allocation fail\n");
}*/
if((deviceAddr.sin_addr.s_addr = INADDR_ANY) == (unsigned long)INADDR_NONE)
{
// in netdb.h
printf("[%s:%d#%s] Host Not found(%d)\n",__FILE__, __LINE__,__func__, h_errno);
close(m_SendSocketId); // close the socket
return false;
}
if (bind(m_SendSocketId, (struct sockaddr *) &deviceAddr,sizeof(struct sockaddr_in)) < 0 )
{
printf("[%s:%d#%s] UDP Client- Socket Bind error=%s\n",__FILE__, __LINE__,__func__,strerror(errno));
close(m_SendSocketId); // close the socket
return false;
}
// Clear out the server struct
memset(&serverAddr, 0x00, sizeof(struct sockaddr_in));
//Configure Server Address.
//set family and port
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(SERVERPORT);
//serverAddr.sin_addr.s_addr = htonl(39898);
if((serverAddr.sin_addr.s_addr = inet_addr(SERVERIP)) == (unsigned long)INADDR_NONE)
{
printf("[%s:%d#%s] Host Not found %d\n",__FILE__, __LINE__,__func__,h_errno);
close(m_SendSocketId);
return false;
}
// Send data to the server.
if( sendto(m_SendSocketId, message,strlen(message) ,0, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0 )
{
printf("[%s:%d#%s] UDP Client - sendto() error=%s \n",__FILE__, __LINE__,__func__,strerror(errno));
close(m_SendSocketId);
return false;
}
close(m_SendSocketId);
return true;
}
int main ()
{
int loop;
char str[10];
msgcount = 1;
pthread_t receiveThread;
if(pthread_create(&receiveThread, NULL,(void *)&receiveMessage, NULL) != 0)
{
printf("[%s:%d#%s] thread create Failed(%s)\n",
__FILE__, __LINE__,__func__, strerror(errno));
return false;
}
for(loop =0; loop < 1000; loop++)
{
sprintf(str,"%4d",loop);
sendMessage(str);
}
pthread_join(receiveThread, NULL);
return 0;
}
Here is the temporary UDP server code, it receives almost above 90% messages and also sends the same, but udpclient is not able to receive the messages.
int main()
{
int sock;
int addr_len, bytes_read, bytes_send;
char recv_data[1024];
int i;
int count=0;
struct sockaddr_in server_addr , client_addr;
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
perror("Socket");
exit(1);
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(5000);
server_addr.sin_addr.s_addr = INADDR_ANY;
bzero(&(server_addr.sin_zero),8);
//client_addr.sin_family = AF_INET;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
if (bind(sock,(struct sockaddr *)&server_addr,sizeof(struct sockaddr)) == -1)
{
perror("Bind");
exit(1);
}
addr_len = sizeof(struct sockaddr);
printf("\nUDPServer Waiting for client on port 5000");
fflush(stdout);
while (1)
{
bytes_read = recvfrom(sock,recv_data,1024,0,(struct sockaddr *)&client_addr, (socklen_t *)&addr_len);
recv_data[bytes_read] = '\0';
if(recv_data[0]!=0x07)
{
recv_data[0] = 0x09;
//client_addr.sin_port = htons(51254);
bytes_send = sendto(sock, recv_data, bytes_read, 0, (struct sockaddr *)&client_addr, (socklen_t)sizeof(client_addr));
if(bytes_send < 0 )
{
perror("send to ");
}
printf("\nNumber %d", ++count);
memset(&recv_data, 0x00, 1024);
}
else
{
printf("Received Keep ALive\n");
}
memset(&client_addr, 0x00, sizeof(struct sockaddr_in));
fflush(stdout);
}
return 0;
}
Any help would be highly appreciated.
Thanks Yuvi
Your code has nothing to do with UDP dropping packets, except possibly that you are sending packets too fast for the network or the receiver. UDP isn't reliable. It drops packets. If your application protocol requires no dropped packets, you have to build in reliability at that level, via an ACK-based or NACK-based protocol with retries.
Or use TCP like everybody else does in this situation.
The problem was in sendMessage Function, here I was recreating socket every time when I need to send message, and I think that takes time. I don't know yet which is calls are blocking but making sending socket resolves my problem. Now the dropping of message is upto 20 to 30 % only.
My question is:
Server will create a socket, bind to a given port and with address = INADDR_ANY.
listen() & accept() the new connection. Then, we can get the client's ip-address
from accept().
Now, I want to know the ip-address of the Server, since the host of the server has
multiple NIC on it.
How to know the ip-address of the network interface with which the accepted in-bound socket is from?
I tried getsockname, it gave me the port number, but the ip is all-zero.
Update: Here is the code:
Server.c (header files are removed)
int main(void)
{
struct sockaddr_in stSockAddr;
int res, addr_len, SocketFD, ConnectFD;
struct sockaddr_in addr;
SocketFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if(-1 == SocketFD)
{
perror("can not create socket");
//exit(EXIT_FAILURE);
return -1;
}
memset(&stSockAddr, 0, sizeof stSockAddr);
stSockAddr.sin_family = AF_INET;
stSockAddr.sin_port = htons(49335);
stSockAddr.sin_addr.s_addr = INADDR_ANY;
if(-1 == bind(SocketFD,(struct sockaddr *)&stSockAddr, sizeof stSockAddr))
{
perror("error bind failed");
close(SocketFD);
return -1;
}
printf("going to listen!\n");
if(-1 == listen(SocketFD, 10))
{
perror("error listen failed");
close(SocketFD);
//exit(EXIT_FAILURE);
return -1;
}
ConnectFD = accept(SocketFD, NULL, NULL);
if(0 > ConnectFD)
{
perror("error accept failed");
close(SocketFD);
//exit(EXIT_FAILURE);
return -1;
}
addr.sin_family = AF_INET;
res = getsockname (ConnectFD, (struct sockaddr *)&addr, &addr_len);
// if you remove the following comment, that means, if you call
// two times of getsockname, the result will be correct.
//res = getsockname (ConnectFD, (struct sockaddr *)&addr, &addr_len);
printf("addr:%x\n", addr.sin_addr.s_addr);
while(1) {
if (getchar() == 'q')
break;
}
close(ConnectFD);
close(SocketFD);
return 0;
}
Below is client.c:
int main(void)
{
struct sockaddr_in stSockAddr;
int Res;
int SocketFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (-1 == SocketFD)
{
perror("cannot create socket");
exit(EXIT_FAILURE);
}
memset(&stSockAddr, 0, sizeof stSockAddr);
stSockAddr.sin_family = AF_INET;
stSockAddr.sin_port = htons(49335);
Res = inet_pton(AF_INET, "192.168.1.102", &stSockAddr.sin_addr);
if (0 > Res)
{
perror("error: first parameter is not a valid address family");
close(SocketFD);
exit(EXIT_FAILURE);
}
else if (0 == Res)
{
perror("char string (second parameter does not contain valid ipaddress");
close(SocketFD);
exit(EXIT_FAILURE);
}
if (-1 == connect(SocketFD, (struct sockaddr *)&stSockAddr, sizeof stSockAddr))
{
perror("connect failed");
close(SocketFD);
exit(EXIT_FAILURE);
}
/* perform read write operations ... */
printf("client sockfd is successful\n");
while(1) {
if (getchar() == 'q')
break;
}
shutdown(SocketFD, SHUT_RDWR);
close(SocketFD);
return 0;
}
Use getsockname(2) on the socket returned from accept(2), not the socket returned from bind(2).
getsockname() gets name of passed socket.
in this example, you pass the socket which is created by
accept function in server.
this socket is in server side, so it's name & address is
related to server side.
if you want to know "who was connected to me"
you must use getpeername() instead of getsockname.
good luck
if you remove the following comment, that means, if you call
two times of getsockname, the result will be correct.
res = getsockname (ConnectFD, (struct sockaddr *)&addr, &addr_len);
you must init addr_len.
addr_len = sizeof(addr);