Related
I am using a for loop on the server-side to send data to all clients received from a single client. But it is unable to send to all clients. Instead, it just sends data to the only client who has sent the data. And also it is not printing the here printf line on the server console.
for(int j=0;j<i;j++){
printf("here");
send(fds[j], buffer, strlen(buffer), 0);
}
My server-side code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define PORT 9999
int main(int argc, char* argv[]){
int sockfd, ret;
struct sockaddr_in serverAddr;
int newSocket;
struct sockaddr_in newAddr;
char lastchar = 'a';
socklen_t addr_size;
char buffer[1024];
pid_t childpid;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0){
printf("[-]Error in connection.\n");
exit(1);
}
printf("[+]Server Socket is created.\n");
memset(&serverAddr, '\0', sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(PORT);
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
ret = bind(sockfd, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
if(ret < 0){
printf("[-]Error in binding.\n");
exit(1);
}
printf("[+]Bind to port %d\n", 4444);
if(listen(sockfd, 10) == 0){
printf("[+]Listening....\n");
}else{
printf("[-]Error in binding.\n");
}
int fds[10];
int i = 0;
while(1){
newSocket = accept(sockfd, (struct sockaddr*)&newAddr, &addr_size);
fds[i++] = newSocket;
if(newSocket < 0){
exit(1);
}
printf("Connection accepted from %s:%d\n", inet_ntoa(newAddr.sin_addr), ntohs(newAddr.sin_port));
if((childpid = fork()) == 0){
close(sockfd);
while(1){
recv(newSocket, buffer, 1024, 0);
if(strcmp(buffer, ":exit") == 0){
printf("Disconnected from %s:%d\n", inet_ntoa(newAddr.sin_addr), ntohs(newAddr.sin_port));
break;
}else{
if(buffer[0]==lastchar){
lastchar = buffer[strlen(buffer)-1];
bzero(buffer, sizeof(buffer));
strcpy(buffer, "Correct!");
}else{
bzero(buffer, sizeof(buffer));
strcpy(buffer, "Wrong!");
}
for(int j=0;j<i;j++){
printf("here");
send(fds[j], buffer, strlen(buffer), 0);
}
bzero(buffer, sizeof(buffer));
}
}
}
}
close(newSocket);
return 0;
}
My Client-side code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define PORT 9999
int main(){
int clientSocket, ret;
struct sockaddr_in serverAddr;
char buffer[1024];
clientSocket = socket(AF_INET, SOCK_STREAM, 0);
if(clientSocket < 0){
printf("[-]Error in connection.\n");
exit(1);
}
printf("[+]Client Socket is created.\n");
memset(&serverAddr, '\0', sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(PORT);
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
ret = connect(clientSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
if(ret < 0){
printf("[-]Error in connection.\n");
exit(1);
}
printf("[+]Connected to Server.\n");
while(1){
printf("Client: \t");
scanf("%s", &buffer[0]);
send(clientSocket, buffer, strlen(buffer), 0);
if(strcmp(buffer, ":exit") == 0){
close(clientSocket);
printf("[-]Disconnected from server.\n");
exit(1);
}
if(recv(clientSocket, buffer, 1024, 0) < 0){
printf("[-]Error in receiving data.\n");
}else{
printf("Server: \t%s\n", buffer);
}
}
return 0;
}
If I change my server code to the following can anybody tell me how to reply to all clients?
//Example code: A simple server side code, which echos back the received message.
//Handle multiple socket connections with select and fd_set on Linux
#include <stdio.h>
#include <string.h> //strlen
#include <stdlib.h>
#include <errno.h>
#include <unistd.h> //close
#include <arpa/inet.h> //close
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/time.h> //FD_SET, FD_ISSET, FD_ZERO macros
#define TRUE 1
#define FALSE 0
#define PORT 8888
int main(int argc , char *argv[])
{
int opt = TRUE;
int master_socket , addrlen , new_socket , client_socket[30] ,
max_clients = 30 , activity, i , valread , sd;
int max_sd;
struct sockaddr_in address;
char buffer[1025]; //data buffer of 1K
//set of socket descriptors
fd_set readfds;
//a message
char *message = "ECHO Daemon v1.0 \r\n";
//initialise all client_socket[] to 0 so not checked
for (i = 0; i < max_clients; i++)
{
client_socket[i] = 0;
}
//create a master socket
if( (master_socket = socket(AF_INET , SOCK_STREAM , 0)) == 0)
{
perror("socket failed");
exit(EXIT_FAILURE);
}
//set master socket to allow multiple connections ,
//this is just a good habit, it will work without this
if( setsockopt(master_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&opt,
sizeof(opt)) < 0 )
{
perror("setsockopt");
exit(EXIT_FAILURE);
}
//type of socket created
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons( PORT );
//bind the socket to localhost port 8888
if (bind(master_socket, (struct sockaddr *)&address, sizeof(address))<0)
{
perror("bind failed");
exit(EXIT_FAILURE);
}
printf("Listener on port %d \n", PORT);
//try to specify maximum of 3 pending connections for the master socket
if (listen(master_socket, 3) < 0)
{
perror("listen");
exit(EXIT_FAILURE);
}
//accept the incoming connection
addrlen = sizeof(address);
puts("Waiting for connections ...");
while(TRUE)
{
//clear the socket set
FD_ZERO(&readfds);
//add master socket to set
FD_SET(master_socket, &readfds);
max_sd = master_socket;
//add child sockets to set
for ( i = 0 ; i < max_clients ; i++)
{
//socket descriptor
sd = client_socket[i];
//if valid socket descriptor then add to read list
if(sd > 0)
FD_SET( sd , &readfds);
//highest file descriptor number, need it for the select function
if(sd > max_sd)
max_sd = sd;
}
//wait for an activity on one of the sockets , timeout is NULL ,
//so wait indefinitely
activity = select( max_sd + 1 , &readfds , NULL , NULL , NULL);
if ((activity < 0) && (errno!=EINTR))
{
printf("select error");
}
//If something happened on the master socket ,
//then its an incoming connection
if (FD_ISSET(master_socket, &readfds))
{
if ((new_socket = accept(master_socket,
(struct sockaddr *)&address, (socklen_t*)&addrlen))<0)
{
perror("accept");
exit(EXIT_FAILURE);
}
//inform user of socket number - used in send and receive commands
printf("New connection , socket fd is %d , ip is : %s , port : %d
\n" , new_socket , inet_ntoa(address.sin_addr) , ntohs
(address.sin_port));
//send new connection greeting message
if( send(new_socket, message, strlen(message), 0) != strlen(message) )
{
perror("send");
}
puts("Welcome message sent successfully");
//add new socket to array of sockets
for (i = 0; i < max_clients; i++)
{
//if position is empty
if( client_socket[i] == 0 )
{
client_socket[i] = new_socket;
printf("Adding to list of sockets as %d\n" , i);
break;
}
}
}
//else its some IO operation on some other socket
for (i = 0; i < max_clients; i++)
{
sd = client_socket[i];
if (FD_ISSET( sd , &readfds))
{
//Check if it was for closing , and also read the
//incoming message
if ((valread = read( sd , buffer, 1024)) == 0)
{
//Somebody disconnected , get his details and print
getpeername(sd , (struct sockaddr*)&address , \
(socklen_t*)&addrlen);
printf("Host disconnected , ip %s , port %d \n" ,
inet_ntoa(address.sin_addr) , ntohs(address.sin_port));
//Close the socket and mark as 0 in list for reuse
close( sd );
client_socket[i] = 0;
}
//Echo back the message that came in
else
{
//set the string terminating NULL byte on the end
//of the data read
buffer[valread] = '\0';
send(sd , buffer , strlen(buffer) , 0 );
}
}
}
}
return 0;
}
When you call fork(), the child process effectively receives its own separate copy of the parent process's address-space. Since the child process's address-space is separate and independent from that of its parent process, any subsequent changes to variables in the parent process's address space will not be seen by the child process.
Since your server is calling fork() for each new TCP connection that is received, that means that each new TCP connection is getting its own address-space that includes it and any already-accepted sockets, but will never include any sockets that are accepted on the server after that client's process was spawned. That is likely why you aren't seeing all the file descriptors you expect in your fds array, when you iterate over it calling send().
My advice is to simply get rid of the fork() call. If you want to keep (and iterate over) a list of all connected clients' file-descriptors, then its much simpler to use a single-process model rather than a process-per-client model. If you need to react to incoming input data from any of the clients, you can use non-blocking I/O and block instead inside select() or poll() until one of the file descriptors in your list has incoming data ready for you to read.
This question has been asked many times, but searching through and implementing some solutions that have worked for others, I still haven't been able to figure out what I'm doing wrong. I am still having issues understanding programming with sockets, so any explanations would be greatly appreciated. The function where I am getting the error is "int forwardClientReq(char* buffer, char* hostname, int clientfd)" and more specifically around this:
numBytesSent = send(serverfd, buffer, strlen(buffer), 0);
if(numBytesSent == -1)
printf("Oh dear, something went wrong with send()! %s\n", strerror(errno));
The full code is as follows:
/* Proxy application called webproxy */
// Copy past http server includes, remove unnecessary
#include <stdio.h>
#include <stdlib.h>
#include <string.h> /* for fgets */
#include <strings.h> /* for bzero, bcopy */
#include <unistd.h> /* for read, write */
#include <sys/socket.h> /* for socket use */
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <errno.h>
#define MAXBUF 8192 /* max text line length */
#define LISTENQ 1024 /* second argument to listen() */
#define ERRBUFSIZE 1024
#define HEAPBUF 32768 // 2^15
int open_listenfd(int port);
void webProxy(int connfd);
void *thread(void *vargp);
int connect2Client(char* ip, char* port);
void sendErrResponse(char* errBUF, int connfd);
int forwardClientReq(char* buffer, char* host, int clientfd);
int main(int argc, char **argv)
{
int timeout = 0;
/* Check if the function was called correctly */
/* Store arguments provided (port number & cache timeout) */
if(argc < 2 || argc > 3){
fprintf(stderr, "Incorrect arguments, Usage: ./<executableFile> <port#> <timeout(optional)>\n");
exit(0);
}
if(argc == 3)
timeout = atoi(argv[2]);
int listenfd, *connfdp, port, clientlen=sizeof(struct sockaddr_in);
pthread_t tid;
struct sockaddr_in clientaddr;
port = atoi(argv[1]); // store the port number
listenfd = open_listenfd(port); // create persistant TCP socket for client HTTP requests
/* Create,Bind,Listen SOCKET and multithread */
while (1) {
connfdp = malloc(sizeof(int)); // pointer to pass the socket
*connfdp = accept(listenfd, (struct sockaddr*)&clientaddr, &clientlen);
if(*connfdp<0)
printf("There is an error accepting the connection with the client");
pthread_create(&tid, NULL, thread, connfdp); // call thread function with tid
}
}
/* thread routine */
void * thread(void * vargp)
{
int connfd = *((int *)vargp);
pthread_detach(pthread_self());
free(vargp);
webProxy(connfd);
close(connfd);
return NULL;
}
void webProxy(int connfd)
{
size_t n;
char buffer[MAXBUF]; // pointer to pass the socket
char errorBuf[ERRBUFSIZE];
bzero(errorBuf, ERRBUFSIZE);
bzero(buffer, MAXBUF);
char httpmsg[]="HTTP/1.1 200 Document Follows\r\nContent-Type:text/html\r\nContent-Length:32\r\n\r\n<html><h1>Hello CSCI4273 Course!</h1>";
char hostname[50];
n = read(connfd, buffer, MAXBUF); // read the requst up to maxbuf sizeof
printf("server received the following request:\n%s\n",buffer);
/* parse the request */
char requestType[50], fullPath[50];
bzero(requestType, 50);
bzero(fullPath, 50);
sscanf(buffer, "%s %s", requestType, fullPath);
printf("requestType = %s, and fullPath= %s\n", requestType, fullPath);
/* I tried a million different methods and libary suggestions but this is the only
method that I found to easily parse the information I wanted to input */
// sscanf(fullPath, "http://www.%511[^/\n]", hostname);
sscanf(fullPath, "http://%511[^/\n]", hostname);
printf("hostname is = %s\n", hostname);
/* support only GET requests */
if(strcmp(requestType, "GET") != 0)
{
printf("Proxy received a request that was not a 'GET' Request, sending 400 Bad Request response\n");
sendErrResponse(errorBuf, connfd);
}
// // /* support only HTTP/1.1 */
// else if(strcmp(Type, "HTTP/1.1") != 0)
// {
// printf("Proxy received a request that was not an HTTP/1.1 version, sending 400 Bad Request response");
// // I think the error message below is 80, but I could be wrong. Need to double check or use strlen function
// sprintf(errorBuf, "HTTP/1.1 400 Bad Request\r\nContent-Type:text/html\r\nContent-Length: %d\r\n\r\n",80);
// write(connfd, errorBuf, strlen(errorBuf));
// bzero(errorBuf, ERRBUFSIZE);
// }
/* parse and verify the hostname/server */
struct hostent *host = gethostbyname(hostname);
if (host == NULL) {
fprintf(stderr,"ERROR, no such host as %s\n", hostname);
sendErrResponse(errorBuf, connfd);
exit(0);
}
else{
/* Forward request to HTTP server */
forwardClientReq(buffer, hostname, connfd);
printf("buffer = %s\n", buffer);
/* Relay data from server to client */
}
}
int forwardClientReq(char* buffer, char* hostname, int clientfd)
{
char* serverResponse = malloc(HEAPBUF); // create a buffer for receiving the response from the server
bzero(serverResponse, HEAPBUF); // zeroize the buffer
/* open a socket with the server */
struct sockaddr_in serveraddr;
int serverSock, optval =1;
/* Create a socket descriptor */
if(-1 == (serverSock = socket(AF_INET, SOCK_STREAM, 0))) // yoda condition...
{
printf("Error: Unable to create socket in 'open_listenfd' function");
return -1;
}
/* Eliminates "Address already in use" error from bind. */
if (setsockopt(serverSock, SOL_SOCKET, SO_REUSEADDR, &optval , sizeof(int)) < 0){
printf("Error in setsockopt in forwardClientReq function");
return -1;
}
struct hostent* host = gethostbyname(hostname);
serveraddr.sin_family = AF_INET;
memcpy(&serveraddr.sin_addr, host->h_addr_list[0], host->h_length);
serveraddr.sin_port = htons(80); //(you should pick the correct remote port or use the default 80 port if noneis specified).
socklen_t addrlen = sizeof(serveraddr); // The addrlen argument specifies the size of serveraddr.
int serverfd = connect(serverSock, (struct sockaddr*) &serveraddr, addrlen);
if(serverfd < 0)
printf("improper connection when trying to forward client's request/n");
/* send the client message to the server */
int numBytesSent = 0;
printf("buffer before send = %s\n", buffer);
sprintf(buffer, "\r\n\r\n");
numBytesSent = send(serverfd, buffer, strlen(buffer), 0);
if(numBytesSent == -1)
printf("Oh dear, something went wrong with send()! %s\n", strerror(errno));
// printf("Sent %d to the server", numBytesSent);
// /* store the server's response */
// int numBytesRead = 0;
// numBytesRead = read(serverfd, serverResponse, HEAPBUF);
// printf("Sent %d to the server", numBytesRead);
//
// /* send the response to the client. This is a moment here the proxy can cache the page,
// inspect the data, and do all kinds of cool proxy-level things */
// numBytesSent = write(clientfd, serverResponse, strlen(serverResponse));
// printf("Sent %d to the server", numBytesSent);
free(serverResponse); // free malloc'd space
}
int open_listenfd(int port)
{
int listenfd, optval=1;
struct sockaddr_in serveraddr;
/* Create a socket descriptor */
if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("Error: Unable to create socket in 'open_listenfd' function");
return -1;
}
/* Eliminates "Address already in use" error from bind. */
if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &optval , sizeof(int)) < 0)
return -1;
/* listenfd will be an endpoint for all requests to port
on any IP address for this host */
bzero((char *) &serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
serveraddr.sin_port = htons((unsigned short)port);
/* bind: associate the parent socket with a port */
if (bind(listenfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) < 0)
return -1;
/* Make it a listening socket ready to accept connection requests */
if (listen(listenfd, LISTENQ) < 0)
return -1;
return listenfd;
} /* end open_listenfd */
void sendErrResponse(char* errorBuf, int connfd)
{
// I think the error message below is 80, but I could be wrong. Need to double check or use strlen function
sprintf(errorBuf, "HTTP/1.1 400 Bad Request\r\nContent-Type:text/html\r\nContent-Length: %d\r\n\r\n",80);
write(connfd, errorBuf, strlen(errorBuf));
bzero(errorBuf, ERRBUFSIZE);
}
The return value of connect is an error code not a socket fd:
If the connection or binding succeeds, zero is returned. On error,
-1 is returned, and errno is set appropriately.
So
numBytesSent = send(serverfd, buffer, strlen(buffer), 0);
Should be
numBytesSent = send(serverSock, buffer, strlen(buffer), 0);
I have a UDP Server which sends data continuously. I want to receive all the packets sent by the server.
On server side I have two threads. One thread continuously reads data from the file and puts into deque. Another thread reads data from the deque and sends to the UDP client continuously. The client code continuously receives data from the server.
I have variables to keep the count of the number of bytes sent in server code and the number of bytes received in client code.
There is huge difference between the two. The server sends about 93 MB but the client receives only 3 - 5 MB.
How can I receive all the data sent by the Server?
Please find the server and client code below.
Server Code:
#define MAX_BUFFER_SIZE 1400
typedef struct
{
T_UCHAR buffer[MAX_BUFFER_SIZE];
DWORD buf_size;
}RAWDATA_LOG;
deque<RAWDATA_LOG> m_RawdataLog;
void TransmitContinuous()
{
if (m_sock_type_tcp == SOCK_UDP)
{
fileReadComplete=false;
//start data transmission thread
pWin_thread=AfxBeginThread(StartDataTransmitThread, (LPVOID) this);
ReadFromFile();
}
}
void ReadFromFile()
{
int bytesRead=0;
m_no_of_bytes = MAX_BUFFER_SIZE;
BYTE input_buf[MAX_BUFFER_SIZE]={'\0'};
GetDlgItemText(IDEBC_FILENAME,m_fileInput);
m_InputFile=NULL;
/*opening the file to read*/
m_InputFile = _tfopen(m_fileInput,L"rb");
if(m_InputFile == NULL)
{
AfxMessageBox(L"Unable to open the Input file");
}
else
{
while(!feof(m_InputFile))
{
bytesRead=fread(input_buf,1,m_no_of_bytes,m_InputFile);
writeRawdataToDeque(input_buf,m_no_of_bytes);
noofBytesReadfromFile+=bytesRead;
}
fileReadComplete=true;
}
}
void writeRawdataToDeque(T_UCHAR *buffer,T_S32 size)
{
T_S32 temp_size = size;
T_S32 size_counter = 0;
RAWDATA_LOG temp_rawDataStruct;
while(temp_size>0)
{
if(temp_size <= MAX_BUFFER_SIZE)
{
memcpy(temp_rawDataStruct.buffer,&buffer[size_counter],temp_size);
temp_rawDataStruct.buf_size = temp_size;
noofBytesWrittentoDeque+=temp_size;
}
else
{
memcpy(temp_rawDataStruct.buffer,&buffer[size_counter],sizeof(temp_rawDataStruct.buffer));
temp_rawDataStruct.buf_size = MAX_BUFFER_SIZE;
noofBytesWrittentoDeque+=MAX_BUFFER_SIZE;
}
CSingleLock datalock(&m_Cs_RawDataLog);
datalock.Lock();
m_RawdataLog.push_back(temp_rawDataStruct);
datalock.Unlock();
memset(&temp_rawDataStruct,0,sizeof(temp_rawDataStruct));
size_counter += MAX_BUFFER_SIZE;
temp_size = temp_size - MAX_BUFFER_SIZE;
}
}
unsigned int StartDataTransmitThread (LPVOID param)
{
RAWDATA_LOG temp_rawDataBuf;
int byesWritten=0;
CString tmpStr;
while(1)
{
if(!m_RawdataLog.empty())
{
CSingleLock datalock(&m_Cs_RawDataLog);
datalock.Lock();
temp_rawDataBuf = m_RawdataLog.front();
m_RawdataLog.pop_front();
datalock.Unlock();
//transmit the data through socket
byesWritten=WritetoClient(clientIp,clientPort,(const LPBYTE)&temp_rawDataBuf, MAX_BUFFER_SIZE);
noofBytesTransmitted+=byesWritten;
}
else
{
if(fileReadComplete == true)
{
break;
}
}
}
return true;
}
bool CreateServer(char ipaddr[],int port)
{
sockaddr_in ServerSockAddr;
WORD m_wVersionRequested;
WSADATA m_wsaData;
int m_wsaErr;
ServerSockAddr.sin_addr.s_addr=inet_addr("192.168.11.80");
ServerSockAddr.sin_family = AF_INET;
ServerSockAddr.sin_port = htons(2011);
m_wVersionRequested = MAKEWORD(2, 2);
m_wsaErr = WSAStartup(m_wVersionRequested, &m_wsaData);
if (m_wsaErr != 0)
{
/* Tell the user that we could not find a usable */
/* Winsock DLL. */
MessageBox(L"WSAStartup failed with error:" + m_wsaErr);
return 1;
}
SOCKET sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
if (INVALID_SOCKET != sock)
{
if ( SOCKET_ERROR == bind(sock,(struct sockaddr *) & ServerSockAddr, sizeof(ServerSockAddr)))
{
int b= GetLastError();
closesocket( sock );
return false;
}
}
else
{
closesocket( sock );
return false;
}
m_hComm = (HANDLE) sock;
}
int WritetoClient(char ipaddr[],int port,BYTE buf[],int len)
{
sockaddr_in clientSockAddr;
int res=0;
SOCKET s = (SOCKET) m_hComm;
clientSockAddr.sin_addr.s_addr=inet_addr("192.168.11.80");
clientSockAddr.sin_family = AF_INET;
clientSockAddr.sin_port = htons(port);
res = sendto( s, (const char *)buf, len, 0, (SOCKADDR *) &clientSockAddr, sizeof(clientSockAddr));
return res;
}
Client Code:
#include <stdlib.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment(lib, "ws2_32")
#define BUFSIZE 1000000
int _tmain(int argc, _TCHAR* argv[])
{
SOCKET sockfd;
int portno, n;
int serverlen;
struct sockaddr_in serveraddr;
struct hostent *server;
char *hostname;
char buf[BUFSIZE];
int BytesReceived=0;
int buff_size=1000000;
WORD m_wVersionRequested;
WSADATA m_wsaData;
int m_wsaErr;
m_wVersionRequested = MAKEWORD(2, 2);
m_wsaErr = WSAStartup(m_wVersionRequested, &m_wsaData);
if (m_wsaErr != 0)
{
/* Tell the user that we could not find a usable */
/* Winsock DLL. */
printf("WSAStartup failed with error:");
return 1;
}
/* socket: create the socket */
sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
if (sockfd < 0)
{
printf("ERROR opening socket");
}
else
{
/* build the server's Internet address */
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(2010);
serveraddr.sin_addr.s_addr=inet_addr("192.168.11.80");
/* send the message to the server */
serverlen = sizeof(serveraddr);
setsockopt(sockfd,SOL_SOCKET,SO_RCVBUF,(char *)(&buff_size), sizeof(buff_size));
if ( SOCKET_ERROR == bind(sockfd,(struct sockaddr *) & serveraddr, sizeof(serveraddr)))
{
printf("Bind Error");
int a = GetLastError();
printf("Error ID:%d",a);
}
else
{
printf("Reading From Server:\n");
while(1)
{
n = recvfrom(sockfd, buf, sizeof(buf), 0,(struct sockaddr *) &serveraddr, &serverlen);
if (n < 0)
{
printf("ERROR in recvfrom\n");
int b = GetLastError();
printf("Error ID:%d\n",b);
}
else
{
BytesReceived+=n;
TRACE("\nTotal Bytes Received:%d\n",BytesReceived);
}
}
}
}
getchar();
return 0;
}
I see a couple of issues with your code.
On the server side, you are binding the server's socket to 192.168.11.80 AND you are sending packets to 192.168.11.80 as well, instead of sending them to whichever IP address is specified in the ipaddr parameter of the WritetoClient() function.
On the client side, you are bind()'ing the client's socket to the server's IP address.
This setup will only work if the client and server are running on the same machine. It will not work between multiple machines connected through a network.
You need to bind the client to an IP address that is local to the client's own machine, not to the server's IP address. And your server needs to send packets to the IP address that the client is actually bound to.
If you want to ensure that your client receives data only from the server's IP address, and not from other machines that may happen to be sending data over the same network, you can optionally connect() the client's socket to the server's IP address (yes, you can use connect() with UDP).
bind() is for establishing a socket's local IP address. connect() is for establishing a socket's remote/peer IP address.
Since you are (potentially) not binding the client's socket correctly, and/or (potentially) not sending to the correct IP, you are likely receiving data that you are not expecting from somewhere else. That could explain the large discrepancy you are seeing. I would suggest having your client output the data it actually receives, so you can make sure it is receiving what you are expecting, eg:
n = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr *) &serveraddr, &serverlen);
if (n == SOCKET_ERROR)
{
int b = WSAGetLastError();
printf("ERROR in recvfrom\nError ID:%d\n",b);
}
else
{
BytesReceived += n;
TRACE("\nMessage Received from %s:%hu: '%.*s'", inet_ntoa(serveraddr.sin_addr), ntohs(serveraddr.sin_port), n, buf);
TRACE("\nTotal Bytes Received: %d\n", BytesReceived);
}
Hello I made this program based on the msdn winsock2.h tutorial.I have server program and a client one.Everything works fine, I even made one sided chat from the server to the client, more like broadcast.Now i want to see the client's IP address when he connects.I think i did it right but, on every connect it shows different address in strange form like 12.2.90.0 then, 12.2.46.0.
This is the server code :
#include <cstdlib>
#include <iostream>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <iphlpapi.h>
#define DEFAULT_PORT "27015"
using namespace std;
int main(int argc, char *argv[])
{
WSADATA wsaData;
int iResult;
SOCKET ListenSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;
struct sockaddr_in client_info;
char * addr;
struct addrinfo *result = NULL;
struct addrinfo hints;
int iSendResult;
char buffer[50];
char typebuffer[50];
char connected_ip[15]= "\0";
int port;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
} cout<<"Winsock initialized..."<<endl;
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
// Resolve the server address and port
iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
if ( iResult != 0 ) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
// Create a SOCKET for connecting to server
ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (ListenSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
return 1;
}
// Setup the TCP listening socket
iResult = bind( ListenSocket, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR) {
printf("bind failed with error: %d\n", WSAGetLastError());
freeaddrinfo(result);
closesocket(ListenSocket);
WSACleanup();
return 1;
} else cout<<"Listening socket initialized...\nAccepting connections now..."<<endl;
freeaddrinfo(result);
iResult = listen(ListenSocket, SOMAXCONN);
if (iResult == SOCKET_ERROR) {
printf("listen failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
// Accept a client socket
ClientSocket = accept(ListenSocket, (struct sockaddr*)&client_info, NULL);
if (ClientSocket == INVALID_SOCKET) {
printf("accept failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
} else
// converting the address in readable form
addr = inet_ntoa(client_info.sin_addr);
printf("Client connected, IP address is: %s\n", addr );
{
}
closesocket(ListenSocket);
for(;;)
{
cin.getline(typebuffer,50);
strcpy(buffer,"SERVER: ");
strcat(buffer,typebuffer);
send( ClientSocket, buffer, 50, 0 );
*buffer = '\0';
}
system("PAUSE");
return EXIT_SUCCESS;
}
You are providing a sockaddr_in struct to accept(), but you are not telling it how large the struct is. You are not zeroing out the sockaddr_in, and accept() is not filling it in, so you end up with random results when calling inet_ntoa(). This behavior is documented:
accept function
If addr and/or addrlen are equal to NULL, then no information about the remote address of the accepted socket is returned.
The addrlen parameter cannot be NULL if the addr parameter is not NULL:
int addrlen = sizeof(client_info); // <-- Add this
ClientSocket = accept(ListenSocket, (struct sockaddr*)&client_info, &addrlen);
I received the error: `connect failed: connection refused` from the following code. Server side code runs fine, but when I run the client side I get the connect failed error. I am using Ubuntu.
server side run: `./server.out 1234`
client side run: `.client.out 127.0.0.1 input.txt 1234`
Client code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
//#include "Practical.h"
// check error
void DieWithError(char *errorMessage)
{
perror(errorMessage);
exit(1);
}
void DieWithUserMessage(const char *msg, const char *detail) {
fputs(msg, stderr);
fputs(": ", stderr);
fputs(detail, stderr);
fputc('\n', stderr);
exit(1);
}
void DieWithSystemMessage(const char *msg) {
perror(msg);
exit(1);
}
//define buffer size
enum sizeConstants {
MAXSTRINGLENGTH = 128,
BUFSIZE = 512,
};
int main(int argc, char *argv[]) {
char buffer[BUFSIZE];
//FILE *fp,*fpOut; // declare file pointer
if (argc < 3 || argc > 4) // Test for correct number of arguments
DieWithUserMessage("Parameter(s)","<Server Address> <Echo Word> [<Server Port>]");
char *servIP = argv[1]; // First arg: server IP address (dotted quad)
char *echoString = argv[2]; // Second arg: string to echo
// Third arg (optional): server port (numeric). 7 is well-known echo port
in_port_t servPort = (argc == 4) ? atoi(argv[3]) : 7;
// Create a reliable, stream socket using TCP
int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock < 0)
DieWithSystemMessage("socket() failed");
// Construct the server address structure
struct sockaddr_in servAddr; // Server address
memset(&servAddr, 0, sizeof(servAddr)); // Zero out structure
servAddr.sin_family = AF_INET; // IPv4 address family
// Convert address
int rtnVal = inet_pton(AF_INET, servIP, &servAddr.sin_addr.s_addr);
if (rtnVal == 0)
DieWithUserMessage("inet_pton() failed", "invalid address string");
else if (rtnVal < 0)
DieWithSystemMessage("inet_pton() failed");
servAddr.sin_port = htons(servPort); // Server port
// Establish the connection to the echo server
if (connect(sock, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0)
DieWithSystemMessage("connect() failed");
/*
//start reading file input from computer
char buf[1000];
fp =fopen("input.txt","r");//open the file
if (!fp){
printf("it failed!\n");
return 1;
}
while(fgets (buf, 1000, fp)!=NULL) { // take the file input value in buf char array
//printf("The input value in program.txt file: %s",buf);
printf("Received Message from server: ");
*/
size_t echoStringLen = strlen(echoString); // Determine input length
// Send the string to the server
ssize_t numBytes = send(sock, echoString, echoStringLen, 0);
if (numBytes < 0)
DieWithSystemMessage("send() failed");
else if (numBytes != echoStringLen)
DieWithUserMessage("send()", "sent unexpected number of bytes");
// Receive the same string back from the server
unsigned int totalBytesRcvd = 0; // Count of total bytes received
// Setup to print the echoed string
while (totalBytesRcvd < echoStringLen) {
// I/O buffer
/* Receive up to the buffer size (minus 1 to leave space for
a null terminator) bytes from the sender */
numBytes = recv(sock, buffer, BUFSIZE - 1, 0);
if (numBytes < 0)
DieWithSystemMessage("recv() failed");
else if (numBytes == 0)
DieWithUserMessage("recv()", "connection closed prematurely");
totalBytesRcvd += numBytes; // Keep tally of total bytes
buffer[numBytes] = '\0'; // Terminate the string!
printf("%s",buffer);
//fputs(buffer, stdout); // Print the echo buffer
}
//fpOut = fopen("gcd.txt","w"); // open the gcd txt file in write mode
//fprintf(fpOut,"%s",buffer );// write the gcd value in gcd text file
//fputc('\n', stdout);
//fclose(fpOut);
//fclose(fp);
return 0;
close(sock);
exit(0);
}
Server code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
//#include "Practical.h"
void DieWithError(char *errorMessage)
{
perror(errorMessage);
exit(1);
}
void DieWithUserMessage(const char *msg, const char *detail) {
fputs(msg, stderr);
fputs(": ", stderr);
fputs(detail, stderr);
fputc('\n', stderr);
exit(1);
}
void DieWithSystemMessage(const char *msg) {
perror(msg);
exit(1);
}
static const int MAXPENDING = 5; // Maximum outstanding connection requests
int main(int argc, char *argv[]) {
if (argc != 2) // Test for correct number of arguments
DieWithUserMessage("Parameter(s)", "<Server Port>");
in_port_t servPort = atoi(argv[1]); // First arg: local port
// Create socket for incoming connections
int servSock; // Socket descriptor for server
if ((servSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
DieWithSystemMessage("socket() failed");
// Construct local address structure
struct sockaddr_in servAddr; // Local address
memset(&servAddr, 0, sizeof(servAddr)); // Zero out structure
servAddr.sin_family = AF_INET; // IPv4 address family
servAddr.sin_addr.s_addr = htonl(INADDR_ANY); // Any incoming interface
servAddr.sin_port = htons(servPort); // Local port
// Bind to the local address
if (bind(servSock, (struct sockaddr*) &servAddr, sizeof(servAddr)) < 0)
DieWithSystemMessage("bind() failed");
// Mark the socket so it will listen for incoming connections
if (listen(servSock, MAXPENDING) < 0)
DieWithSystemMessage("listen() failed");
for (;;) { // Run forever
struct sockaddr_in clntAddr; // Client address
// Set length of client address structure (in-out parameter)
socklen_t clntAddrLen = sizeof(clntAddr);
printf("\nIam here\n");
// Wait for a client to connect
int clntSock = accept(servSock, (struct sockaddr *) &clntAddr, &clntAddrLen);
if (clntSock < 0)
DieWithSystemMessage("accept() failed");
// clntSock is connected to a client!
char clntName[INET_ADDRSTRLEN]; // String to contain client address
if (inet_ntop(AF_INET, &clntAddr.sin_addr.s_addr, clntName,sizeof(clntName)) != NULL)
printf("Got response from client: %s/%d\n", clntName, ntohs(clntAddr.sin_port));
else
puts("Unable to get client address");
HandleTCPClient(clntSock);
}
// NOT REACHED
}
HandleTCPClient:`#define RCVBUFSIZE 1024 /* Size of receive buffer */
void DieWithError(char errorMessage); / Error handling function */
void HandleTCPClient(int clntSocket) {
FILE *fp;
char echoBuffer[RCVBUFSIZE]; /* Buffer for echo string */
int recvMsgSize; /* Size of received message */
/* Receive message from client */
if ((recvMsgSize = recv(clntSocket, echoBuffer, RCVBUFSIZE, 0)) < 0)
DieWithError("recv() failed");
printf("Server asked file name from Client side:: %s", echoBuffer);
fp =fopen("echoBuffer","r");//open the file
if (!fp){
printf("it failed!\n");
//return 1;
}
//int i,j;
//sscanf(echoBuffer, "%d %d", &i,&j);// take the two number from client and convert string to integer.
//sprintf(echoBuffer,"%d",gcd(i,j)); // call the gcd method.
/* Send received string and receive again until end of transmission */
while (recvMsgSize > 0){ /* zero indicates end of transmission */
/* Echo message back to client */
if (send(clntSocket, echoBuffer, recvMsgSize, 0) != recvMsgSize)
DieWithError("send() failed");
/* See if there is more data to receive */
if ((recvMsgSize = recv(clntSocket, echoBuffer, RCVBUFSIZE, 0)) < 0)
DieWithError("recv() failed");
}
fclose(fp);
close(clntSocket); /* Close client socket */
}
HandleTCPclient received command from client like input.txt and check that file and send back to the client but i got segmentation fault(core dumped). here input.txt contain just one text file
enter code here
Your code is not using your supplied port, but it trying to connect to 7, you may not have a echo server running. Try changing to
in_port_t servPort = (argc ==4) ? atoi(argv[3]) : 7;