| | |
Client/Server sockets and reading a file
Please support our C++ advertiser: Intel Parallel Studio Home
![]() |
•
•
Join Date: Jan 2008
Posts: 77
Reputation:
Solved Threads: 0
So, what Im trying to do here is a client server socket program. The client will ask a question to the server. For example, How are you?
Then the server opens a text file, compares the string from the client and outputs the answer to the client.
My text file is something like this.
How are you? I am fine.
so client asks How are you?
server outputs to client I am fine.
So far I have tried compiling my code and there seems to be a compilation error. If I do not include the file reading and string checking, the client/server socket code works fine. As in I can make the server repeat whatever the client inputs.
Then the server opens a text file, compares the string from the client and outputs the answer to the client.
My text file is something like this.
How are you? I am fine.
so client asks How are you?
server outputs to client I am fine.
So far I have tried compiling my code and there seems to be a compilation error. If I do not include the file reading and string checking, the client/server socket code works fine. As in I can make the server repeat whatever the client inputs.
C++ Syntax (Toggle Plain Text)
#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #include <iostream> #include <cstring> #include <string> #include <fstream> #include <vector> #include <cstdlib> #include <iostream> using namespace std; enum { RECV_PORT = 5000, MSGSIZE = 1024 }; const char fileName[30] = "file.txt"; char* s; char input[255]; char* result = NULL; string qns, ans; socklen_t addr_len = sizeof(sockaddr) ; int server( int socket_fd ) { sockaddr_in my_addr ; std::memset( &my_addr, 0, sizeof(my_addr) ) ; my_addr.sin_family = AF_INET ; my_addr.sin_port = htons( RECV_PORT ) ; my_addr.sin_addr.s_addr = INADDR_ANY ; if ( bind( socket_fd, (sockaddr*)&my_addr, addr_len ) != 0 ) return 2 ; fstream infile(fileName); while( true ) { infile.open(fileName); char recv_data[MSGSIZE+1] ; sockaddr_in client_addr ; int bytes_recd = recvfrom( socket_fd, recv_data, MSGSIZE, 0, (sockaddr*)&client_addr, &addr_len ) ; if( bytes_recd == -1 ) break ; else recv_data[bytes_recd] = '\0' ; { infile.getline(input,255, '\n'); while(!infile.eof()) { vector<string> parts; std::string tmpstr(input); s = input; result = strtok(s, " "); while (result != NULL) { if (result != "" && result != "?.!") { parts.push_back(result); } result = strtok(NULL, "?.!"); } qns = parts[0]; ans = parts[1]; if (recv_data.compare(qns)==0) std::cout << ans << std::endl; } } std::cout << "from " << inet_ntoa(client_addr.sin_addr) << ':' << ntohs(client_addr.sin_port) << " - " << recv_data << std::endl ; } return 0 ; } int client( int socket_fd ) { std::cout << "Enter Address to connect: " ; std::string address ; std::cin >> address >> std::ws ; sockaddr_in peer_addr ; std::memset( &peer_addr, 0, sizeof(peer_addr) ) ; peer_addr.sin_family = AF_INET ; peer_addr.sin_port = htons( RECV_PORT ) ; peer_addr.sin_addr.s_addr = *(in_addr_t*)(gethostbyname( address.c_str() )->h_addr) ; std::string send_str ; while( std::getline( std::cin, send_str ) ) { send_str.resize(MSGSIZE) ; sendto( socket_fd, send_str.c_str(), MSGSIZE, 0, (sockaddr*)&peer_addr, addr_len ) ; } return 0 ; } int main() { int socket_fd = socket( AF_INET, SOCK_DGRAM, 0 ) ; if( socket_fd == -1 ) return 1 ; return fork() == 0 ? server( socket_fd ) : client( socket_fd ) ; }
First... I wouldn't make the text file in that way. I'd use a delimiter. Such as:
This saves you the hassle of having to guess where the client sentence ends and the server sentence should begin. You already know... it's because of the :. I suppose the same could be said about the ?, but what if it now becomes a statement? Using a standard delimiter makes life that much easier.
As far as the code goes... it looks to me like your second strtok might throw things off
C++ Syntax (Toggle Plain Text)
Hello, How are you?:I'm fine.
As far as the code goes... it looks to me like your second strtok might throw things off
result = strtok(NULL, "?.!"); doesn't match up with your first strtok, which is splitting by " ", not ?.!. You said above that there seems to be a compilation error... if so, what is the error? ah, yes. You could take the char array, and convert it to string, and then compare. While a bit of a pain I suppose:
I think you could just do a simple == at that point though.
C++ Syntax (Toggle Plain Text)
std::string tmpvar(recv_data); if (tmpvar.compare(qns) == 0)
I think you could just do a simple == at that point though.
if (tmpvar == qns) { •
•
Join Date: Jan 2008
Posts: 77
Reputation:
Solved Threads: 0
ok so now my code compiles properly. However, it doesnt work. I am able to input a question like How are you?
but nothing else happens. It should be able to create a fork and the server side of my code should be comparing the input with the file and displaying the answer.
Is there anything wrong with my file reading loop?
but nothing else happens. It should be able to create a fork and the server side of my code should be comparing the input with the file and displaying the answer.
Is there anything wrong with my file reading loop?
C++ Syntax (Toggle Plain Text)
#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #include <iostream> #include <cstring> #include <string> #include <fstream> #include <vector> #include <cstdlib> #include <iostream> using namespace std; enum { RECV_PORT = 5000, MSGSIZE = 1024 }; const char fileName[30] = "file.txt"; char* s; char input[255]; char* result = NULL; string qns, ans; socklen_t addr_len = sizeof(sockaddr) ; int server( int socket_fd ) { sockaddr_in my_addr ; std::memset( &my_addr, 0, sizeof(my_addr) ) ; my_addr.sin_family = AF_INET ; my_addr.sin_port = htons( RECV_PORT ) ; my_addr.sin_addr.s_addr = INADDR_ANY ; if ( bind( socket_fd, (sockaddr*)&my_addr, addr_len ) != 0 ) return 2 ; fstream infile(fileName); while( true ) { infile.open(fileName); char recv_data[MSGSIZE+1] ; sockaddr_in client_addr ; int bytes_recd = recvfrom( socket_fd, recv_data, MSGSIZE, 0, (sockaddr*)&client_addr, &addr_len ) ; if( bytes_recd == -1 ) break ; else recv_data[bytes_recd] = '\0' ; { infile.getline(input,255, '\n'); while(!infile.eof()) { vector<string> parts; std::string tmpstr(input); s = input; result = strtok(s, ":"); while (result != NULL) { if (result != "" && result != ":") { parts.push_back(result); } result = strtok(NULL, ":"); } qns = parts[0]; ans = parts[1]; std::string tmpvar(recv_data); if (tmpvar == qns) std::cout << ans << std::endl; } } /*=====echo recv_data===== std::cout << "from " << inet_ntoa(client_addr.sin_addr) << ':' << ntohs(client_addr.sin_port) << " - " << recv_data << std::endl ;*/ } return 0 ; } int client( int socket_fd ) { std::cout << "Enter Address to connect: " ; std::string address ; std::cin >> address >> std::ws ; sockaddr_in peer_addr ; std::memset( &peer_addr, 0, sizeof(peer_addr) ) ; peer_addr.sin_family = AF_INET ; peer_addr.sin_port = htons( RECV_PORT ) ; peer_addr.sin_addr.s_addr = *(in_addr_t*)(gethostbyname( address.c_str() )->h_addr) ; std::string send_str ; while( std::getline( std::cin, send_str ) ) { send_str.resize(MSGSIZE) ; sendto( socket_fd, send_str.c_str(), MSGSIZE, 0, (sockaddr*)&peer_addr, addr_len ) ; } return 0 ; } int main() { int socket_fd = socket( AF_INET, SOCK_DGRAM, 0 ) ; if( socket_fd == -1 ) return 1 ; return fork() == 0 ? server( socket_fd ) : client( socket_fd ) ; }
Without looking through all your code, I see this thing:
What is that brace doing there? That code block will always be executed, because the {}-block isn't part of any if/else/while/for block.
else
recv_data[bytes_recd] = '\0' ;
{
infile.getline(input,255, '\n');
while(!infile.eof())What is that brace doing there? That code block will always be executed, because the {}-block isn't part of any if/else/while/for block.
Last edited by niek_e; Feb 16th, 2009 at 9:07 am.
What I meant was: the braces are in the wrong place. The open brace should be directly after 'else'. How much experience do you have with c/c++? Perhaps you might want to read up on a if/else tutorial
•
•
Join Date: Jan 2008
Posts: 77
Reputation:
Solved Threads: 0
forgot to mention that in my above post, but i tried putting the braces as you advised too. Both removing and changing the position of the braces resulted in the program doing nothing. Im not new to if else....
I am new to this socket and not sure how to integrate a file read/manipulation with the server part. As I said the echoing of input is fine. I believe it's the file read which makes my program not work but I don't know which part of the logic is wrong.
I am new to this socket and not sure how to integrate a file read/manipulation with the server part. As I said the echoing of input is fine. I believe it's the file read which makes my program not work but I don't know which part of the logic is wrong.
Last edited by number87; Feb 17th, 2009 at 8:36 pm.
![]() |
Similar Threads
- Winsock Multi-Client Servers (C++)
- Socket Programming (C)
- Program does not read through correctly (C)
- Help with multithread server (C)
- Zend PHP Certification (PHP)
- Can't remove "about:blank" homepage. Please help. (Viruses, Spyware and other Nasties)
Other Threads in the C++ Forum
- Previous Thread: Urgent: Need Help Writing Simple Program for length and width
- Next Thread: "Errors during compilation of makefile"
| Thread Tools | Search this Thread |
Tag cloud for C++
api application array arrays based beginner binary c++ c/c++ calculator char char* class classes code coding compile compiler console conversion convert count data database delete deploy developer display dll dynamiccharacterarray email encryption error file format forms fstream function functions game generator givemetehcodez graph homeworkhelp iamthwee ifstream image input int java lib list loop looping loops map math matrix memory multiple newbie news number numbertoword output pointer problem program programming project python random read recursion recursive reference return rpg simple sorting spoonfeeding string strings struct template templates text tree url variable vector video visual visualstudio void win32 windows winsock wordfrequency wxwidgets






