Used strtok to parse a string and now I am having difficulties with my IF statement. Suspect that I am using the wrong case (value vs. address) but I have run out of ideas. Any help would be greatly appreciated.
I used a series of printf to confirm that strtok populated "hldType" correctly. Thanks again for any help. I have been stuck on this for days.
The abbreviated code is below. The full code source is also included.
char *hldType; /* Parsing holding field */
static const char *REQTYPE = "0"; /* Comparison */
hldType = strtok(echoBuffer, "."); /* Parse the string */
if (strcmp(hldType,REQTYPE) == 0) /* NOT WORKING */
printf("REQTYPE myString: %s\n", REQTYPE);
CODE:
#include <stdio.h> /* for printf() and fprintf() */
#include <sys/socket.h> /* for socket() and bind() */
#include <arpa/inet.h> /* for sockaddr_in and inet_ntoa() */
#include <stdlib.h> /* for atoi() and exit() */
#include <string.h> /* for memset() */
#include <unistd.h> /* for close() */
#include <time.h> /* Display time */
#define ECHOMAX 255 /* Longest string to echo */
void DieWithError(char *errorMessage); /* External error handling function */
/* User Defined type */
typedef struct _ServerMessage{
enum {New, Old, No_Message} messageType; /* same size as an unsigned int */
unsigned int SenderId; /* unique client identifier */
unsigned int RecipientId; /* unique client identifier */
char message[100]; /* text message */
} ServerMessage; /* an unsigned int is 32 bits = 4 bytes */
int main(int argc, char *argv[])
{
int sock; /* Socket */
struct sockaddr_in echoServAddr; /* Local address */
struct sockaddr_in echoClntAddr; /* Client address */
unsigned int cliAddrLen; /* Length of incoming message */
char echoBuffer[ECHOMAX]; /* Buffer for echo string */
unsigned short echoServPort; /* Server port */
int recvMsgSize; /* Size of received message */
char *hldType; /* Parsing holding field */
char *hldSend; /* Parsing holding field */
char *hldRecip; /* Parsing holding field */
char *hldMsg; /* Parsing holding field */
char tmpType[1]; /* Type of action requested by client, where 0 is Send and 1 is Received */
static const char *REQTYPE = "0";
/* Test Struct */
/*ServerMessage ServerMessage_new = {No_Message, 1234,5678,"Hello Server World - No Message"}; */
ServerMessage ServerMessage_new[100];
/* printf("Message Type: %d\n", ServerMessage_new.messageType);
printf("Message SenderID: %04d\n", ServerMessage_new.SenderId);
printf("Message RecipentID: %04d\n", ServerMessage_new.RecipientId);
printf("Message Content: %s\n", ServerMessage_new.message); */
if (argc != 2) /* Test for correct number of parameters */
{
fprintf(stderr,"Usage: %s <UDP SERVER PORT>\n", argv[0]);
exit(1);
}
echoServPort = atoi(argv[1]); /* First arg: local port */
/* Create socket for sending/receiving datagrams */
if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
DieWithError("socket() failed");
/* Construct local address structure */
memset(&echoServAddr, 0, sizeof(echoServAddr)); /* Zero out structure */
echoServAddr.sin_family = AF_INET; /* Internet address family */
echoServAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */
echoServAddr.sin_port = htons(echoServPort); /* Local port */
/* Bind to the local address */
if (bind(sock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0)
DieWithError("bind() failed");
for (;;) /* Run forever */
{
/* Set the size of the in-out parameter */
cliAddrLen = sizeof(echoClntAddr);
/* Block until receive message from a client */
if ((recvMsgSize = recvfrom(sock, echoBuffer, ECHOMAX, 0,
(struct sockaddr *) &echoClntAddr, &cliAddrLen)) < 0)
DieWithError("recvfrom() failed");
printf("Handling client %s\n", inet_ntoa(echoClntAddr.sin_addr));
/* Parse string from client */
printf("echoBuffer Content: %s\n", echoBuffer);
hldType = strtok(echoBuffer, ".");
hldSend = strtok(NULL, ".");
hldRecip = strtok(NULL, ".");
hldMsg = strtok(NULL, ".");
printf("value of hldType: %s\n", hldType); /* Validated that it prints "0" */
/* Store message sent from client */
time_t now;
time(&now);
printf("%s", ctime(&now));
if (strcmp(hldType,REQTYPE) == 0) /* NOT WORKING */
printf("REQTYPE myString: %s\n", REQTYPE);
ServerMessage_new[0].messageType = atoi(hldType);
printf("hldType Content: %d\n", ServerMessage_new[0].messageType);
ServerMessage_new[0].SenderId = atoi(hldSend);
printf("hldSend Content: %04d\n", ServerMessage_new[0].SenderId);
ServerMessage_new[0].RecipientId = atoi(hldRecip);
printf("hldRecip Content: %04d\n", ServerMessage_new[0].RecipientId);
strncpy(ServerMessage_new[0].message, hldMsg, 40);
printf("hldMsg Content: %s\n", ServerMessage_new[0].message);
/* Send received datagram back to the client */
if (sendto(sock, echoBuffer, recvMsgSize, 0,
(struct sockaddr *) &echoClntAddr, sizeof(echoClntAddr)) != recvMsgSize)
DieWithError("sendto() sent a different number of bytes than expected");
}
/* NOT REACHED */
}
Try this:
printf( "comparing [%s] to [%s]\n", hldType, REQTYPE);
if (strcmp(hldType,REQTYPE) == 0) /* NOT WORKING */
printf("REQTYPE myString: %s\n", REQTYPE);
You may find extra whitespace in one of your strings. You can also print the return value from calling strcmp().
If hldType and REQTYPE are both "0", then strcmp() should be returning 0 (equal).
I think strtok isn't finding any parseable tokens. I mean, there's no "." in the input string. Check it.
Related
hello i was recently given this server/client program in c that is supposed to be okay and not have any mistakes. problem is every time i try to run it i get the message the program is supposed to print when there are not enough arguments (even though i give the port number and the message i want it to echo) could anyone help me find what i am doing wrong? thank you in advance for any help you give me. the code i wanna run is the following:
server :
#include <stdio.h> /* for printf() and fprintf() */
#include <sys/socket.h> /* for socket(), connect(), send(), and recv() */
#include <arpa/inet.h> /* for sockaddr_in and inet_addr() */
#include <stdlib.h> /* for atoi() */
#include <string.h> /* for memset() */
#include <unistd.h> /* for close() */
#define MAXPENDING 5 /* Maximum outstanding connection requests */
#define RCVBUFSIZE 32 /*Size of receive buffer*/
void DieWithError(char *errorMessage); /* Error handling function */
void HandleTCPClient(int clntSocket);/* TCP client handling function */
int main(int argc, char *argv[]) {
int servSock; /* Socket descriptor for server */
int clntSock; /* Socket descriptor for client */
struct sockaddr_in echoServAddr; /* Local address */
struct sockaddr_in echoClntAddr; /* Client address */
unsigned short echoServPort; /* Server port */
unsigned int clntLen; /* Length of client address data structure */
if (argc != 2) {/* Test for correct number of arguments */
fprintf(stderr, "Usage: %s <Server Port>\n", argv[0]) ;
exit(1);
}
echoServPort = atoi(argv[1]); /* First arg: local port */
/* Create socket for incoming connections */
if ((servSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
DieWithError( "socket () failed") ;
/* Construct local address structure */
memset(&echoServAddr, 0, sizeof(echoServAddr)); /* Zero out structure */
echoServAddr.sin_family = AF_INET; /* Internet address family */
echoServAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */
echoServAddr.sin_port = htons(echoServPort); /* Local port */
/* Bind to the local address */
if (bind(servSock, (struct sockaddr *)&echoServAddr, sizeof(echoServAddr)) < 0)
DieWithError ( "bind () failed");
/* Mark the socket so it will listen for incoming connections */
if (listen(servSock, MAXPENDING) < 0)
DieWithError("listen() failed") ;
for (;;) {/* Run forever */
/* Set the size of the in-out parameter */
clntLen = sizeof(echoClntAddr);
/* Wait for a client to connect */
if ((clntSock = accept(servSock, (struct sockaddr *) &echoClntAddr, &clntLen)) < 0)
DieWithError("accept() failed");
/* clntSock is connected to a client! */
printf("Handling client %s\n", inet_ntoa(echoClntAddr.sin_addr));
HandleTCPClient (clntSock) ;
}
/* NOT REACHED */
}
void DieWithError(char *errorMessage){
perror(errorMessage);
exit(1);
}
void HandleTCPClient(int clntSocket) {
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") ;
/* 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") ;
}
close(clntSocket); /* Close client socket */
}
the client is the following:
#include <stdio.h> /* for printf() and fprintf() */
#include <sys/socket.h> /* for socket(), connect(), send(), and recv() */
#include <arpa/inet.h> /* for sockaddr_in and inet_addr() */
#include <stdlib.h> /* for atoi() */
#include <string.h> /* for memset() */
#include <unistd.h> /* for close() */
#define RCVBUFSIZE 32 /* Size of receive buffer */
void DieWithError(char *errorMessage); /* Error handling function */
int main(int argc, char *argv[]) {
int sock; /* Socket descriptor */
struct sockaddr_in echoServAddr; /* Echo server address */
unsigned short echoServPort; /* Echo server port */
char *servIP; /* Server IP address (dotted quad) */
char *echoString; /* String to send to echo server */
char echoBuffer[RCVBUFSIZE]; /* Buffer for echo string */
unsigned int echoStringLen; /* Bytes read in single recv()*/
int bytesRcvd, totalBytesRcvd; /*total bytes read */
if ((argc<3) || (argc>4)) {
fprintf(stderr, "Usage: %s <Server IP> <Echo Word> [<Echo Port>]\n", argv[0]);
exit(1);
}
servIP = argv[1] ; /* First arg' server IP address (dotted quad) */
echoString = argv[2] ;/* Second arg' string to echo */
if (argc == 4)
echoServPort = atoi(argv[3]); /* Use given port, if any */
else
echoServPort = 7; /* 7 is the well-known port for the echo service */
/* Create a reliable, stream socket using TCP */
if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
DieWithError(" socket () failed") ;
/* Construct the server address structure */
memset(&echoServAddr, 0, sizeof(echoServAddr)); /* Zero out structure */
echoServAddr.sin_family = AF_INET; /* Internet address family */
echoServAddr.sin_addr.s_addr = inet_addr(servIP); /* Server IP address */
echoServAddr.sin_port = htons(echoServPort); /* Server port */
/* Establish the connection to the echo server */
if (connect(sock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0)
DieWithError(" connect () failed") ;
echoStringLen = strlen(echoString) ; /* Determine input length */
/* Send the string to the server */
if (send(sock, echoString, echoStringLen, 0) != echoStringLen)
DieWithError("send() sent a different number of bytes than expected");
/* Receive the same string back from the server */
totalBytesRcvd = 0;
printf("Received: "); /* Setup to print the echoed string */
while (totalBytesRcvd < echoStringLen) {
/* Receive up to the buffer size (minus 1 to leave space for
a null terminator) bytes from the sender */
if ((bytesRcvd = recv(sock, echoBuffer, RCVBUFSIZE - 1, 0)) <= 0)
DieWithError("recv() failed or connection closed prematurely");
totalBytesRcvd += bytesRcvd; /* Keep tally of total bytes */
echoBuffer[bytesRcvd] = '\0'; /* Terminate the string! */
printf(echoBuffer); /* Print the echo buffer */
}
printf("\n"); /* Print a final linefeed */
close(sock);
exit(0);
}
void DieWithError(char *errorMessage){
perror(errorMessage);
exit(1);
}
Correct me if I'm wrong, but I assume the problem is that you are inputting the wrong parameters, and are getting the "Usage: ..." error message?
Provided you compile it correctly, the programs should run with something like the following commands:
./server 1200
./client localhost message 1200
The server program accepts only 1 parameter, and the client program accepts 2 or 3 parameters. The server should also be run before the client.
I am getting a seg fault before main even runs. I am rusty with c and cannot find the error. Previous searches have said that if a struct is too large this can happen. I am using addrinfo, and as you can see I've tried malloc'ing it and I still seg fault before main
#include <stdio.h>
/* for printf() and fprintf() */
#include <sys/socket.h>
/* for socket(), connect(), send(), and recv() */
#include <arpa/inet.h>
/* for sockaddr_in and inet_addr() */
#include <stdlib.h>
/* for atoi() and exit() */
#include <string.h>
/* for memset() */
#include <unistd.h>
/* for close() */
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#define RCVBUFSIZE 32
/* Size of receive buffer */
void DieWithError(char *errorMessage){}; /* Error handling function */
int main(int argc, char *argv[])
{
int sock; /* Socket descriptor */
struct addrinfo hints, *servInfo; /*holds the result of getaddrinfo */
int rttOption; /* Echo server port */
char *servIP; /* Server IP address (dotted quad) */
char *portNumber; /* String to send to echo server */
char echoBuffer[RCVBUFSIZE]; /* Buffer for echo string */
unsigned int echoStringLen; /* Length of string to echo */
int bytesRcvd, totalBytesRcvd; /* Bytes read in single recv() and total bytes read */
int status;
servInfo = (struct addrinfo *) malloc (sizeof(struct addrinfo));
char *httpGetRequest = "GET /";
char *partOfRequest = "HTTP/1.0\r\nConnection: keep-alive\r\n\r\n";
strcpy(httpGetRequest, servIP);
strcpy(httpGetRequest, partOfRequest);
echoStringLen = strlen(httpGetRequest);
if ((argc < 3) || (argc > 4)) /* Test for correct number of arguments */
{
fprintf(stderr, "Usage: %s <Server URL/IP> <Port Number> [<Option -p>]\n",
argv[0]);
exit(1);
}
printf("Check after parsing");
servIP = argv[1]; /* First arg: server IP address (dotted quad) */
portNumber = argv[2]; /* Second arg: string to echo */
if (argc == 4 && *argv[3] == 'p')
{
rttOption = 1; //print out the rtt
}
/* Construct the server address structure */
memset(&hints, 0, sizeof(hints)); /* Zero out structure */
hints.ai_family = AF_UNSPEC; /* Internet address family */
hints.ai_socktype = SOCK_STREAM;
//getting the linked list?
if(status = getaddrinfo(servIP, portNumber, &hints, &servInfo) < 0)
{
DieWithError("getaddrinfo() failed");
}
/* Create a reliable, stream socket using TCP */
if ((sock = socket(servInfo->ai_family, servInfo->ai_socktype, servInfo->ai_protocol)) < 0)
{
DieWithError("socket() failed");
}
/* Establish the connection to the echo server */
if (connect(sock, servInfo->ai_addr, servInfo->ai_addrlen) < 0)
{
DieWithError("connect() failed");
}
printf("Check");
/* Send the string to the server */
if (send (sock, httpGetRequest, echoStringLen, 0) != echoStringLen)
{
DieWithError("send() sent a different number of bytes than expected");
}
/* Receive the same string back from the server */
totalBytesRcvd = 0;
printf("Received: "); /* Setup to print the echoed string */
while (totalBytesRcvd < echoStringLen)
{
/* Receive up to the buffer size (minus 1 to leave space for a null terminator) bytes from the sender */
if ((bytesRcvd = recv(sock, httpGetRequest, RCVBUFSIZE -1, 0)) <= 0)
{
DieWithError("recv() failed or connection closed prematurely");
}
totalBytesRcvd += bytesRcvd; /* Keep tally of total bytes */
echoBuffer[bytesRcvd] = '\0'; /* Terminate the string! */
printf("%s", httpGetRequest); /* Print the echo buffer */
}
printf("\n"); /* Print a final linefeed */
close(sock);
exit(0);
return 0;
}
I expect getting at least hitting the error catch for command line inputs. But instead we are core dumping before we get there.
You don't initialize servIP before using it.
This line causes the issue:
strcpy(httpGetRequest, servIP);
You also cannot modify httpGetRequest.
The line above also causes this issue.
Allocate memory for httpGetRequest in some way, and, combined with the other change, your code is fine.
This pertains to attempting to validate the return address in recvfrom() (the fifth argument to the function) in this UDP echo client:
While I can send data to the server and receive return communications correctly, I'm having trouble validating the return IP address when comparing the fromAddr.sin_addr and echoServAddr.sin_addr.
The goal here is to compare the address in the structure that was used in sendto() and the address in the structure returned from recvfrom() to validate the echo reply from the server indeed came from where the initial transmission from the client was sent (A rudimentary POC that there wasn't a Man In The Middle).
What should I be looking at in order to appropriately validate the return address as it is returned from recvfrom() matches the address transmitted to as referenced in the sendto() call?
#include <stdio.h> /* for printf() and fprintf() */
#include <sys/socket.h> /* for socket(), connect(), sendto(), and recvfrom() */
#include <arpa/inet.h> /* for sockaddr_in and inet_addr() */
#include <stdlib.h> /* for atoi() and exit() */
#include <string.h> /* for memset() */
#include <unistd.h> /* for close() */
#define ECHOMAX 255 /* Longest string to echo */
void DieWithError(char *errorMessage); /* External error handling function */
int main(int argc, char *argv[])
{
int sock; /* Socket descriptor */
struct sockaddr_in echoServAddr; /* Echo server address */
struct sockaddr_in fromAddr; /* Source address of echo */
unsigned short echoServPort; /* Echo server port */
unsigned int fromSize; /* In-out of address size for recvfrom() */
char *servIP; /* IP address of server */
char *echoString; /* String to send to echo server */
char echoBuffer[ECHOMAX+1]; /* Buffer for receiving echoed string */
int echoStringLen; /* Length of string to echo */
int respStringLen; /* Length of received response */
// manage the command line arguments and errors
if ((argc < 3) || (argc > 4)) {
fprintf(stderr, "Usage: %s <Server IP> <Echo Word> [<Echo Port>]\n",
argv[0]);
exit(1);
}
// load servIP
servIP = argv[1];
// load echoString
echoString = argv[2];
// check echoString and error if too long
echoStringLen = strlen(echoString);
if (!(echoStringLen <= 255)) {
DieWithError("BUFFER EXCEEDED ERROR");
}
// load port
if (argc == 4)
echoServPort = atoi(argv[3]);
else
echoServPort = 7;
// create the socket
if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
DieWithError("SOCKET CREATION ERROR");
}
/* Construct the server address structure */
memset(&echoServAddr, 0, sizeof(echoServAddr)); /* Zero out structure */
echoServAddr.sin_family = AF_INET; /* Internet addr family */
echoServAddr.sin_addr.s_addr = inet_addr(servIP); /* Server IP address */
echoServAddr.sin_port = htons(echoServPort); /* Server port */
// send the string
inet_pton(AF_INET, servIP, &echoServAddr.sin_addr);
if ((sendto(sock, echoString, strlen(echoString), 0, (struct sockaddr *)
&echoServAddr, sizeof(echoServAddr))) < 0) {
DieWithError("SEND ERROR");
}
// recieve a response
respStringLen = recvfrom(sock, echoBuffer, sizeof(echoBuffer), 0,
(struct sockaddr *) &fromAddr, &fromSize);
if (respStringLen < 0) {
DieWithError("RECV ERROR");
}
// print the message sent
printf("SENT FROM CLIENT: '%s'\n", echoString);
// print the message recieved
echoBuffer[respStringLen] = '\0';
printf("RECEIVED FROM SERVER: '%s'\n", echoBuffer);
// check if from the correct server
if ((struct sockaddr *) &echoServAddr.sin_addr != (struct sockaddr *) &fromAddr.sin_addr) {
DieWithError("INVALID RETURN ADDRESS");
}
// close the socket
close(sock);
// exit the program
exit(0);
}
If the source IP/port of the incoming packet is the same as the destation IP/port of the packet you sent, then the sin_addr and sin_port fields of echoServAddr and fromAddr should match.
This line of code however doesn't do that:
if ((struct sockaddr *) &echoServAddr.sin_addr != (struct sockaddr *) &fromAddr.sin_addr) {
This is comparing the address of echoServAddr.sin_addr against the address of fromAddr.sin_addr. Because these are two separate variables, this will always be false. You instead want:
if ((echoServAddr.sin_addr.s_addr != fromAddr.sin_addr.s_addr) ||
(echoServAddr.sin_port != fromAddr.sin_port))
I am trying to implement the following code for a simple FTP between a client and a server. The problem is, when the server sends the file to the client, the file is empty. I'm not sure what the problem is. I'm assuming the problem lies when the server sends the file. Below is the code.
/*Server Code*/
#ifndef unix
#define WIN32
#include <windows.h>
#include <winsock.h>
#else
#define closesocket close
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <netdb.h>
#endif
#include <stdio.h>
#include <string.h>
#define PROTOPORT 5193 /* default protocol port number */
#define QLEN 6 /* size of request queue */
int visits = 0; /* counts client connections */
main(argc, argv)
int argc;
char *argv[];
{
struct hostent *ptrh; /* pointer to a host table entry */
struct protoent *ptrp; /* pointer to a protocol table entry */
struct sockaddr_in sad; /* structure to hold server.s address */
struct sockaddr_in cad; /* structure to hold client.s address */
int sd, sd2; /* socket descriptors */
int port; /* protocol port number */
int alen; /* length of address */
char buf_recv[1000],buf_send[1000]; /* buffer for string the server sends */
char file_buffer[10000],f_buffer[1000];
int n;
FILE *fp;
#ifdef WIN32
WSADATA wsaData;
WSAStartup(0x0101, &wsaData);
#endif
memset((char *)&sad,0,sizeof(sad)); /* clear sockaddr structure */
sad.sin_family = AF_INET; /* set family to Internet */
sad.sin_addr.s_addr = INADDR_ANY; /* set the local IP address */
if (argc > 1) { /* if argument specified */
port = atoi(argv[1]);
} else {
port = PROTOPORT; /* use default port number */
}
if (port > 0) /* test for illegal value */
sad.sin_port = htons((u_short)port);
else { /* print error message and exit */
fprintf(stderr,"bad port number %s\n",argv[1]);
exit(1);
}
/* Map TCP transport protocol name to protocol number */
if ( ((int)(ptrp = getprotobyname("tcp"))) == 0) {
fprintf(stderr, "cannot map \"tcp\" to protocol number");
exit(1);
}
/* Create a socket */
sd = socket(PF_INET, SOCK_STREAM, ptrp->p_proto);
if (sd < 0) {
fprintf(stderr, "socket creation failed\n");
exit(1);
}
/* Bind a local address to the socket */
if (bind(sd, (struct sockaddr *)&sad, sizeof(sad)) < 0) {
fprintf(stderr,"bind failed\n");
exit(1);
}
/* Specify size of request queue */
if (listen(sd, QLEN) < 0) {
fprintf(stderr,"listen failed\n");
exit(1);
}
alen = sizeof(cad);
if ( (sd2=accept(sd, (struct sockaddr *)&cad, &alen)) < 0) {
fprintf(stderr, "accept failed\n");
exit(1);
}
sprintf(buf_send,"Please enter the file name: ");
send(sd2,buf_send,strlen(buf_send),0);
n=recv(sd2,buf_recv,1000,0);
buf_recv[n]='\0';
printf("%s\n",buf_recv);
fflush(stdout);
if((fp = fopen(buf_recv,"r"))==NULL)
{
sprintf(buf_send,"File could not be found!!!");
exit(0);
} else
sprintf(buf_send,"File found!!!\n");
send(sd2,buf_send,strlen(buf_send),0);
n=recv(sd2,buf_recv,1000,0);
printf("%s",buf_recv);
fflush(stdout);
while(!feof(fp)) {
fgets(f_buffer,1000,fp);
if (feof(fp))
break;
strcat(file_buffer,f_buffer);
}
fclose(fp);
send(sd2,file_buffer,strlen(file_buffer),0);
closesocket(sd2);
exit(0);
}
The Client Code:
/*Client Code*/
#ifndef unix
#define WIN32
#include <windows.h>
#include <winsock.h>
#else
#define closesocket close
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#endif
#include <stdio.h>
#include <string.h>
#define PROTOPORT 5193 /* default protocol port number */
extern int errno;
char localhost[] = "localhost"; /* default host name */
main(argc, argv)
int argc;
char *argv[];
{
struct hostent *ptrh; /* pointer to a host table entry */
struct protoent *ptrp; /* pointer to a protocol table entry */
struct sockaddr_in sad; /* structure to hold an IP address */
int sd; /* socket descriptor */
int port; /* protocol port number */
char *host; /* pointer to host name */
int n; /* number of characters read */
char buf_recv[1000],buf_send[100]; /* buffer for data from the server */
char *filename;
char file_buffer[10000];
FILE *fp;
#ifdef WIN32
WSADATA wsaData;
WSAStartup(0x0101, &wsaData);
#endif
memset((char *)&sad,0,sizeof(sad)); /* clear sockaddr structure */
sad.sin_family = AF_INET; /* set family to Internet */
if (argc > 2) { /* if protocol port specified */
port = atoi(argv[2]); /* convert to binary */
} else {
port = PROTOPORT; /* use default port number */
}
if (port > 0) /* test for legal value */
sad.sin_port = htons((u_short)port);
else { /* print error message and exit */
fprintf(stderr,"bad port number %s\n",argv[2]);
exit(1);
}
/* Check host argument and assign host name. */
if (argc > 1) {
host = argv[1]; /* if host argument specified */
} else {
host = localhost;
}
/* Convert host name to equivalent IP address and copy to sad. */
ptrh = gethostbyname(host);
if ( ((char *)ptrh) == NULL ) {
fprintf(stderr,"invalid host: %s\n", host);
exit(1);
}
memcpy(&sad.sin_addr, ptrh->h_addr, ptrh->h_length);
/* Map TCP transport protocol name to protocol number. */
if ( ((int)(ptrp = getprotobyname("tcp"))) == 0) {
fprintf(stderr, "cannot map \"tcp\" to protocol number");
exit(1);
}
/* Create a socket. */
sd = socket(PF_INET, SOCK_STREAM, ptrp->p_proto);
if (sd < 0) {
fprintf(stderr, "socket creation failed\n");
exit(1);
}
/* Connect the socket to the specified server. */
if (connect(sd, (struct sockaddr *)&sad, sizeof(sad)) < 0) {
fprintf(stderr,"connect failed\n");
exit(1);
}
n = recv(sd, buf_recv, sizeof(buf_recv), 0);
buf_recv[n]='\0';
printf("%s",buf_recv);
scanf("%s",buf_send);
send(sd,buf_send,strlen(buf_send),0);
n = recv(sd, buf_recv, sizeof(buf_recv), 0);
buf_recv[n]='\0';
printf("%s",buf_recv);
fflush(stdout);
sprintf(buf_send,"Client acknowledges, Sending file now.\n");
send(sd,buf_send, strlen(buf_send),0);
n=recv(sd, file_buffer, sizeof(file_buffer), 0);
file_buffer[n]='\0';
fflush(stdout);
fp = fopen("transferredFile.TXT","w");
fputs(file_buffer,fp);
fclose(fp);
closesocket(sd);
exit(0);
}
Is the problem coming from the server sending or is it the client receiving? Thanks!
Server: 'strcat(file_buffer,f_buffer);' - concat to uninitialized array.
Server and Client: assumptions that data contains no nulls, ie. system cannnot transfer binary data, only text.
Server and Client - assumptions that all the file data will fit in one line.
Server and Client - assumptions that TCP can transfer messages larger than one byte.
Probably other bugs associated with TCP streaming and C null-terminated strings.
Hell all. I was working on a server c project, using UDP for a whois service.
But I got error: "No whois is service on this host." Here's my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <pwd.h>
#define BACKLOG 5 /* # of requests we're willing to queue */
#define MAXHOSTNAME 32 /* maximum host name length we tolerate */
main(argc,argv)
int argc; /* standard UNIX argument declarations */
char *argv[];
{
int s,t; /* socket descriptors */
int i; /* general purpose integer */
struct sockaddr_in sa,isa; /* Internet socket address structure */
struct hostent *hp; /* result of host name lookup */
char *myname; /* pointer to name of this program */
struct servent *sp; /* result of service lookup */
char localhost[MAXHOSTNAME+1]; /* local host name as character string */
myname = argv[0];
/*
* Look up the WHOIS service entry
*/
if((sp = getservbyname("whois","udp")) == NULL){
fprintf(stderr, "%s: No whois service on this host\n", myname);
exit(1);
}
/*
* Get our own host information
*/
gethostname(localhost, MAXHOSTNAME);
if((hp = gethostbyname(localhost)) == NULL){
fprintf(stderr, "%s: cannot get local host info?\n", myname);
exit(1);
}
printf("host name is: %s\n",hp->h_name);
printf("my name is: %s\n",myname);
/*
* Put the WHOIS socket number and our address info into the socket structure
*/
u_short portbase = 0;
portbase = 5000;
sa.sin_port = sp->s_port;
sa.sin_port = htons(ntohs((u_short)sp->s_port)+portbase);
bcopy((char *)hp->h_addr, (char *)&sa.sin_addr, hp->h_length);
sa.sin_family = hp->h_addrtype;
/*
* Allocate an open socket for incoming connections
*/
if((s = socket(hp->h_addrtype, SOCK_DGRAM, 0)) < 0){
perror("socket");
exit(1);
}
/*
* Bind the socket to the service port
*/
if(bind(s, (struct sockaddr *)&sa, sizeof sa) < 0){
perror("bind");
exit(1);
}
/*
* Set maximum connections we will fall behind
*/
//listen(s,BACKLOG);
/*
* Go into an infinite loop waiting for new connections
*/
while(1){
i = sizeof isa;
/*
* We hang in accept() while waiting for new customers
*/
/*
if((t = accept(s, (struct sockaddr *)&isa, &i)) < 0){
perror("accept");
exit(1);
}
*/
whois(s); /* perform the actual WHOIS service */
close(s);
}
}
/*
* Get the WHOIS request from remote host and format a reply.
*/
whois(sock)
int sock;
{
struct sockaddr_in clientAddr;
socklen_t len = sizeof(clientAddr);
memset(&clientAddr, 0, sizeof(clientAddr));
struct passwd *p;
char buf[BUFSIZ+1];
int i;
/*
* Get one line request
*/
printf("start to recv data\n");
if((i = recvfrom(sock, buf, BUFSIZ, 0, (struct sockaddr*)&clientAddr, &len)) <= 0)
printf("recv failed\n");
return;
buf[i] = '\0'; /* Null terminate */
printf("After the read, the buf is: %s \n",buf);
/*
* Look up the requested user and format reply
*/
if((p = getpwnam(buf)) == NULL)
strcpy(buf, "User not found\n");
else
sprintf(buf, "%s: %s (from me)\n", p->pw_name, p->pw_gecos);
/*
* Return reply
*/
//write(sock, buf, strlen(buf));
sendto(sock, buf, strlen(buf), 0, (struct sockaddr*)&clientAddr, len);
return;
}
I couldn't figure out where's error. I have a similar code using TCP for whois which runs no problem.
WHOIS is a TCP service. It is not available over UDP.
Additionally, what you are writing is not a WHOIS server at all. WHOIS is a protocol implemented by domain and IP registrars to communicate ownership information (e.g, to look up the owner of a domain name). What you are writing here appears to be a NIS service of some sort - this is not WHOIS, and should not use the same port.