I have simple webserver:
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <err.h>
#include <string.h>
#include <boost/regex.hpp>
#include <boost/thread.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string.hpp>
#include "print_r.h"
#include "Pop.h"
#include "Headers.h"
//#include<thread>
char response[] = "HTTP/1.1 200 OK\r\n"
"Content-Type: text/html; charset=UTF-8\r\n"
"Connection: keep-alive\r\n"
"Server: michal\r\n"
"Set-Cookie: nazwa=test\r\n"
"Date: Mon, 24 Feb 2014 11:39:26 GMT\r\n"
"Vary: Accept-Encoding\r\n\r\n"
"<html><body><h1>It works!</h1>"
"<p>This is the default web page for this server.</p>"
"<p>The web server software is running but no content has been added, yet.</p>"
"<form method='post' action='/' enctype='multipart/form-data' ><input type='file' name='pliczek1'/><input type='submit' name='sub' value='sender' /><input type='checkbox' name='add[]' value='100001_used' ><input type='hidden' name='hidd' value='testowy hiddenik' /><input type='checkbox' name='add[]' value='100002_used' ><textarea name='txtform'>tekstowe poleąś</textarea></form>"
"</body></html>\r\n\r\n";
void app(int client_fd)
{
int buffSize = 512;
char buff[buffSize];
std::string headers = "";
int i = 0;
int npos = 0;
int a = 0;
while (i = recv(client_fd, buff, buffSize, 0))
{
std::cout << i << "\n";
bzero(buff, buffSize);
a++;
if (i < buffSize) break;
}
write(client_fd, response, sizeof(response) - 1); /*-1:'\0'*/
close(client_fd);
}
int main()
{
int one = 1, client_fd;
struct sockaddr_in svr_addr, cli_addr;
socklen_t sin_len = sizeof(cli_addr);
std::cout << sizeof(cli_addr);
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0)
err(1, "can't open socket");
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int));
int port = 8080;
svr_addr.sin_family = AF_INET;
svr_addr.sin_addr.s_addr = INADDR_ANY;
svr_addr.sin_port = htons(port);
if (bind(sock, (struct sockaddr *) &svr_addr, sizeof(svr_addr)) == -1) {
close(sock);
err(1, "Can't bind");
}
listen(sock, 5);
while (1) {
client_fd = accept(sock, (struct sockaddr *) &cli_addr, &sin_len);
std::cout << "\n\n+++++++++++++ NEW CLIENT +++++++++++++++\n\n\n";
if (client_fd == -1) {
std::cout << ("Can't accept\n");
break;
}
app(client_fd);
}
}
I am trying to send an attachment via the web browser. With files smaller than 21kB it works fine but I can't send more than 21845 bytes. Why?
You broke a very important rule: Always check the return value of API calls.
In particular, you don't check the return value of write, you just assume it succeeds. In reality, it often only sends part of the message, so you need a loop and error checking.
Try to read with a small delay between recv calls. You are not guaranteed to receive all data in one go. You have to wait for all the data.
Related
I'm trying to do an HTTP request using sockets on Linux, and my function works now, but only with simple domains as www.google.com or webpage.000webhostapp.com. When I try to add a path and query like webpage.000webhostapp.com/folder/file.php?parameter=value, it starts failing.
This is my code:
#include <iostream>
#include <cstring>
#include <string>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
int main(){
int socket_desc;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[4096];
std::string url = "www.exampleweb.com/folder/file.php";
socket_desc = socket(AF_INET, SOCK_STREAM, 0);
if(socket_desc < 0){
std::cout<<"failed to create socket"<<std::endl;
}
server = gethostbyname(url.c_str());
if(server==NULL){std::cout<<"could Not resolve hostname :("<<std::endl;}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(80);
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
if(connect(socket_desc, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0){
std::cout<<"connection failed :("<<std::endl;
}
std::string request = "GET / HTTP/1.1\r\nHost: " + url + "\r\nConnection: close\r\n\r\n";
if(send(socket_desc, request.c_str(), strlen(request.c_str())+1, 0) < 0){
std::cout<<"failed to send request..."<<std::endl;
}
int n;
std::string raw_site;
while((n = recv(socket_desc, buffer, sizeof(buffer)+1, 0)) > 0){
int i = 0;
while (buffer[i] >= 32 || buffer[i] == '\n' || buffer[i] == '\r'){
raw_site+=buffer[i];
i += 1;
}
}
std::cout<<raw_site<<std::endl;
return 0;
}
Using www.google.com, it works perfectly for the request.
Using www.example.com/folder/file.php?parameter=value¶meter2=value2, it fails and returns "could not resolve hostname".
Any idea on how to fix it?
I'm not using curl and can't use it for this project.
gethostbyname() (which BTW is deprecated, you should be using getaddrinfo() instead) does not work with URLs, only with host names.
Given a URL like http://www.exampleweb.com/folder/file.php?parameter=value¶meter2=value2, you need to first break it up into its constituent pieces (read RFC 3986), eg:
the scheme http
the host name www.exampleweb.com
the resource path /folder/file.php
the query ?parameter=value¶meter2=value2
You can then resolve the IP address for the host, connect to that IP address on port 80 (the default port for HTTP) since the URL doesn't specify a different port, and finally send a GET request for the resource and query.
Also, note that the Host header in the GET request must specify only the host name (and port, if different than the default), not the whole URL. And also that HTTP requests are not null-terminated strings, so do not send the null terminator. Read RFC 2616.
Try this instead:
#include <iostream>
#include <cstring>
#include <string>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
int main(){
int socket_desc;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[4096];
std::string host = "www.exampleweb.com";
std::string port = "80";
std::string resource = "/folder/file.php";
std::string query = "?parameter=value¶meter2=value2";
socket_desc = socket(AF_INET, SOCK_STREAM, 0);
if (socket_desc < 0){
std::cout << "failed to create socket" << std::endl;
return 0;
}
server = gethostbyname(host.c_str());
if (server == NULL){
std::cout << "could Not resolve hostname :(" << std::endl;
close(socket_desc);
return 0;
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(std::stoi(port));
bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length);
if (connect(socket_desc, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0){
std::cout << "connection failed :(" << std::endl;
close(socket_desc);
return 0;
}
std::string request = "GET " + resource + query + " HTTP/1.1\r\nHost: " + host + "\r\nConnection: close\r\n\r\n";
if (send(socket_desc, request.c_str(), request.size(), 0) < 0){
std::cout << "failed to send request..." << std::endl;
close(socket_desc);
return 0;
}
int n;
std::string raw_site;
while ((n = recv(socket_desc, buffer, sizeof(buffer), 0)) > 0){
raw_site.append(buffer, n);
}
close(socket_desc);
std::cout << raw_site << std::endl;
return 0;
}
I'm trying to complete a simple echo server. The goal is to repeat back the message to the client. The server and client both compile.The server is binded to localhost and port 8080. The client has the address, the port, and the message. When the client goes through the program to the sendto section, it stop and waits there. My goal it to have it sent to the server, and the server to send it back.
Problem: The client is send the message and the server is receiving it correctly but the server is not able to return the message. Please help!
SERVER SIDE CODE:
#include <iostream>
#include <string.h>
#include <fstream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define PORT 8080
using namespace std;
int main() {
int serSockDes, len, readStatus;
struct sockaddr_in serAddr, cliAddr;
char buff[1024] = {0};
char msg[] = "Hello to you too!!!\n";
//creating a new server socket
if((serSockDes = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("socket creation error...\n");
exit(-1);
}
//binding the port to ip and port
serAddr.sin_family = AF_INET;
serAddr.sin_port = htons(PORT);
serAddr.sin_addr.s_addr = INADDR_ANY;
if((bind(serSockDes, (struct sockaddr*)&serAddr, sizeof(serAddr))) < 0) {
perror("binding error...\n");
exit(-1);
}
readStatus = recvfrom(serSockDes, buff, 1024, 0, (struct sockaddr*)&cliAddr, (socklen_t*)&len);
buff[readStatus] = '\0';
cout<<buff;
cout<<len;
sendto(serSockDes, msg, strlen(msg), 0, (struct sockaddr*)&cliAddr, len);
return 0;
}
CLIENT SIDE CODE:
#include <iostream>
#include <fstream>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define PORT 8080
using namespace std;
int main(int argc, char** argv) {
int cliSockDes, readStatus, len;
struct sockaddr_in serAddr;
char msg[] = "Hello!!!\n";
char buff[1024] = {0};
//create a socket
if((cliSockDes = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("socket creation error...\n");
exit(-1);
}
//server socket address
serAddr.sin_family = AF_INET;
serAddr.sin_port = htons(PORT);
serAddr.sin_addr.s_addr = INADDR_ANY;
sendto(cliSockDes, msg, strlen(msg), 0, (struct sockaddr*)&serAddr, sizeof(serAddr));
readStatus = recvfrom(cliSockDes, buff, 1024, 0, (struct sockaddr*)&serAddr, (socklen_t*)&len);
buff[readStatus] = '\0';
cout<<buff;
return 0;
}
The client is trying to send its message to INADDR_ANY, which is wrong. It needs to send to a specific IP address instead. The server can listen to all of its local IP addresses using INADDR_ANY, that is fine, but the IP address that the client sends to must be one that the server listens on (or, if the client and server are on different network segments, the client must send to an IP that reaches the server's router, which then must forward the message to an IP that the server is listening on).
Also, your calls to recvfrom() and sendto() on both ends are lacking adequate error handling. In particular, the addrlen parameter of recvfrom() specifies the max size of the sockaddr buffer upon input, and upon output returns the actual size of the peer address stored in the sockaddr. But you are not initializing the len variable that you pass in as the addrlen, so recvfrom() is likely to fail with an error that you do not handle.
Try something more like this instead:
Server:
#include <iostream>
#include <string.h>
#include <fstream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
using namespace std;
#define PORT 8080
int main() {
int serSockDes, readStatus;
struct sockaddr_in serAddr, cliAddr;
socklen_t cliAddrLen;
char buff[1024] = {0};
char msg[] = "Hello to you too!!!\n";
//creating a new server socket
if ((serSockDes = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("socket creation error...\n");
exit(-1);
}
//binding the port to ip and port
serAddr.sin_family = AF_INET;
serAddr.sin_port = htons(PORT);
serAddr.sin_addr.s_addr = INADDR_ANY;
if ((bind(serSockDes, (struct sockaddr*)&serAddr, sizeof(serAddr))) < 0) {
perror("binding error...\n");
close(serSockDes);
exit(-1);
}
cliAddrLen = sizeof(cliAddr);
readStatus = recvfrom(serSockDes, buff, 1024, 0, (struct sockaddr*)&cliAddr, &cliAddrLen);
if (readStatus < 0) {
perror("reading error...\n");
close(serSockDes);
exit(-1);
}
cout.write(buff, readStatus);
cout << endl;
if (sendto(serSockDes, msg, strlen(msg), 0, (struct sockaddr*)&cliAddr, cliAddrLen)) < 0) {
perror("sending error...\n");
close(serSockDes);
exit(-1);
}
close(serSockDes);
return 0;
}
Client:
#include <iostream>
#include <fstream>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
using namespace std;
#define PORT 8080
int main(int argc, char** argv) {
int cliSockDes, readStatus;
struct sockaddr_in serAddr;
socklen_t serAddrLen;
char msg[] = "Hello!!!\n";
char buff[1024] = {0};
//create a socket
if ((cliSockDes = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("socket creation error...\n");
exit(-1);
}
//server socket address
serAddr.sin_family = AF_INET;
serAddr.sin_port = htons(PORT);
serAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
if (sendto(cliSockDes, msg, strlen(msg), 0, (struct sockaddr*)&serAddr, sizeof(serAddr)) < 0) {
perror("sending error...\n");
close(cliSockDes);
exit(-1);
}
serAddrLen = sizeof(serAddr);
readStatus = recvfrom(cliSockDes, buff, 1024, 0, (struct sockaddr*)&serAddr, &serAddrLen);
if (readStatus < 0) {
perror("reading error...\n");
close(cliSockDes);
exit(-1);
}
cout.write(buff, readStatus);
cout << endl;
close(cliSockDes);
return 0;
}
I want to know how to make an HTTP request through a proxy using Socket.
I was looking through documentation on Internet, and many people said that to do it I must connect to the proxy server and send a packet with the following header:
send(Socket, "CONNECT http://icanhazip.com:80 HTTP/1.0\r\n\r\n", strlen("CONNECT http://icanhazip.com:80 HTTP/1.0\r\n\r\n"), 0);
That website returns the current public IP, but, unfortunately, every proxy server I tried returned errors instead of the webpage's HTML source.
This is my actual code:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <iostream>
using namespace std;
int main()
{
try {
int Socket = socket(AF_INET, SOCK_STREAM, 0);
sockaddr_in SockAddr;
memset(&SockAddr, 0, sizeof(SockAddr));
SockAddr.sin_port = htons(80);
SockAddr.sin_family = AF_INET;
SockAddr.sin_addr.s_addr = inet_addr("198.169.246.30");
int iResult = connect(Socket, (struct sockaddr *)& SockAddr, sizeof(SockAddr));
if (iResult != 0) {
std::cout << "I can't connect :(.";
getchar();
return 1;
}
std::cout << "Connected.\n";
send(Socket, "CONNECT http://icanhazip.com:80 HTTP/1.1\r\n\r\n", strlen("CONNECT http://icanhazip.com:80 HTTP/1.1\r\n\r\n"), 0);
char buffer[10000];
int nDataLength;
while ((nDataLength = recv(Socket, buffer, 10000, 0)) > 0) {
int i = 0;
while (buffer[i] >= 32 || buffer[i] == '\n' || buffer[i] == '\r') {
std::cout << buffer[i];
i += 1;
}
}
iResult = close(Socket);
}
catch (...) {
}
return 0;
}
What can I do to fix it? Or, what other solution should I look into?
Old Chinese proverb say, "before writing code, better to read specification"
https://www.rfc-editor.org/rfc/rfc7230
by following links in the document:
A client sending a CONNECT request MUST send the authority form of
request-target (Section 5.3 of [RFC7230]); i.e., the request-target
consists of only the host name and port number of the tunnel
destination, separated by a colon. For example,
CONNECT server.example.com:80 HTTP/1.1
Host: server.example.com:80
source: https://www.rfc-editor.org/rfc/rfc7231#section-4.3.6
I would like to send a string: "Jane Doe" to intranet ip 192.168.0.4 to port 9000 over UDP. I have done this many times via UDP and TCP by Java, but now I have to do it with standard C++ libraries and I can't find any samples only topics where people just can't make it work.
I know that I have to encode "Jane Doe" as array of bytes then just open socket, pack it in datagram and send it.
C++ is not my first language and this is small part of code I can't figure out, I've chosen UDP because it is always much simpler than TCP.
A good source for network programming is Beej's Guide to Network Programming. Below is some sample Unix code.
If this is Windows programming:
"sock" should be of type SOCKET instead of int.
Use closesocket instead of close
#include <winsock2.h> instead of all those unix headers
#include <sys/types.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <memory.h>
#include <ifaddrs.h>
#include <net/if.h>
#include <errno.h>
#include <stdlib.h>
#include <iostream>
int resolvehelper(const char* hostname, int family, const char* service, sockaddr_storage* pAddr)
{
int result;
addrinfo* result_list = NULL;
addrinfo hints = {};
hints.ai_family = family;
hints.ai_socktype = SOCK_DGRAM; // without this flag, getaddrinfo will return 3x the number of addresses (one for each socket type).
result = getaddrinfo(hostname, service, &hints, &result_list);
if (result == 0)
{
//ASSERT(result_list->ai_addrlen <= sizeof(sockaddr_in));
memcpy(pAddr, result_list->ai_addr, result_list->ai_addrlen);
freeaddrinfo(result_list);
}
return result;
}
int main()
{
int result = 0;
int sock = socket(AF_INET, SOCK_DGRAM, 0);
char szIP[100];
sockaddr_in addrListen = {}; // zero-int, sin_port is 0, which picks a random port for bind.
addrListen.sin_family = AF_INET;
result = bind(sock, (sockaddr*)&addrListen, sizeof(addrListen));
if (result == -1)
{
int lasterror = errno;
std::cout << "error: " << lasterror;
exit(1);
}
sockaddr_storage addrDest = {};
result = resolvehelper("192.168.0.4", AF_INET, "9000", &addrDest);
if (result != 0)
{
int lasterror = errno;
std::cout << "error: " << lasterror;
exit(1);
}
const char* msg = "Jane Doe";
size_t msg_length = strlen(msg);
result = sendto(sock, msg, msg_length, 0, (sockaddr*)&addrDest, sizeof(addrDest));
std::cout << result << " bytes sent" << std::endl;
return 0;
}
This is very easy to do if you are willing to use the boost library.
Here is the code snippit
#include "boost/asio.hpp"
using namespace boost::asio;
...
io_service io_service;
ip::udp::socket socket(io_service);
ip::udp::endpoint remote_endpoint;
socket.open(ip::udp::v4());
remote_endpoint = ip::udp::endpoint(ip::address::from_string("192.168.0.4"), 9000);
boost::system::error_code err;
socket.send_to(buffer("Jane Doe", 8), remote_endpoint, 0, err);
socket.close();
I rewrote selbie's code to make it more C++-like and I minimized it a bit.
#include <iostream>
#include <string>
#include <arpa/inet.h> // htons, inet_addr
#include <netinet/in.h> // sockaddr_in
#include <sys/types.h> // uint16_t
#include <sys/socket.h> // socket, sendto
#include <unistd.h> // close
int main(int argc, char const *argv[])
{
std::string hostname{"192.168.0.4"};
uint16_t port = 9000;
int sock = ::socket(AF_INET, SOCK_DGRAM, 0);
sockaddr_in destination;
destination.sin_family = AF_INET;
destination.sin_port = htons(port);
destination.sin_addr.s_addr = inet_addr(hostname.c_str());
std::string msg = "Jane Doe";
int n_bytes = ::sendto(sock, msg.c_str(), msg.length(), 0, reinterpret_cast<sockaddr*>(&destination), sizeof(destination));
std::cout << n_bytes << " bytes sent" << std::endl;
::close(sock);
return 0;
}
For Windows, I took Mikolasan's minimised version of selbie's code and modified according to https://beej.us/guide/bgnet/html/#windows to get a small standalone example.
To get this to compile, you'll need to link the Winsock library.
#include <iostream>
#include <string>
#include <winsock2.h>
int main()
{
// Initialise Winsock DLL
// See https://beej.us/guide/bgnet/html/#windows
WSADATA wsaData;
// MAKEWORD(1,1) for Winsock 1.1, MAKEWORD(2,0) for Winsock 2.0
if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) {
fprintf(stderr, "WSAStartup failed.\n");
exit(1);
}
// Set up connection and send
std::string hostname{ "192.168.0.4" };
uint16_t port = 9000;
SOCKET sock = ::socket(AF_INET, SOCK_DGRAM, 0);
sockaddr_in destination;
destination.sin_family = AF_INET;
destination.sin_port = htons(port);
destination.sin_addr.s_addr = inet_addr(hostname.c_str());
std::string msg = "Jane Doe";
int n_bytes = ::sendto(sock, msg.c_str(), msg.length(), 0, reinterpret_cast<sockaddr*>(&destination), sizeof(destination));
std::cout << n_bytes << " bytes sent" << std::endl;
::closesocket(sock);
// Clean up sockets library
WSACleanup();
return 0;
}
I type two program one for client and one for server.
server is tcp concurrent echo server with select call,in order to use only one process to all client.
it uses apparent concurrency.
I develop program and run its working but after 3/4 message exchange bet client and server.
buffer content at server changes it showing current message with some character from the previous message.
I am not getting why this is happening.
Please anyone able to help me...
//Client Program
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <arpa/inet.h>
#include <iostream>
using namespace std;
#define MAXLINE 4096 /*max text line length*/
#define serv_PORT 3000 /*port*/
int main(int argc,char **argv)
{
int sockfd;
struct sockaddr_in servaddr;
char sendline[MAXLINE];
char recvline[MAXLINE];
/*int sendchars,recvchar;
char buf[MAXLINE];
*/
if (argc !=2)
{
cerr<<"Usage: Femto: <IP address of the serv"<<endl;
exit(1);
}
//Create a socket for the client
if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) <0)
{
cerr<<"Problem in creating the socket"<<endl;
exit(1);
}
//Creation of the socket
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr= inet_addr(argv[1]);
servaddr.sin_port = htons(serv_PORT);
//Connection of the client to the socket
if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr))<0)
{
cerr<<"Problem in connecting to the serv"<<endl;
exit(1);
}
while (fgets(sendline, MAXLINE, stdin) != NULL)
{
send(sockfd, sendline, strlen(sendline), 0);
if (recv(sockfd, recvline, MAXLINE,0) == 0)
{
cerr<<"The serv terminated"<<endl;
exit(1);
}
cout<< "String received from the serv: ";
fputs(recvline, stdout);
}
exit(0);
}
//Server program
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <iostream>
#include <sys/select.h>
#include <sys/time.h>
using namespace std;
#define MAXLINE 4096 /*max text line length*/
#define serv_PORT 3000 /*port*/
#define LISTENQ 65535
int main (int argc, char **argv)
{
int msock,ssock;
fd_set rfds;
fd_set afds;
int fd,nfds;
socklen_t client_len ;
char buf[MAXLINE];
struct sockaddr_in clientaddr, servaddr;
if ((msock = socket (AF_INET, SOCK_STREAM, 0)) <0)
{
cerr<<"Problem in creating the socket"<<endl;
exit(1);
}
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(serv_PORT);
bind (msock, (struct sockaddr *) &servaddr, sizeof(servaddr));
listen (msock, LISTENQ);
nfds=getdtablesize();
FD_ZERO(&afds);
FD_SET(msock,&afds);
while(1)
{
memcpy(&rfds,&afds,sizeof(rfds));
if(select(nfds,&rfds,(fd_set *)0,(fd_set *)0,(struct timeval * )0)<0)
{
cerr<<"Error in select";
// exit(1);
}
if(FD_ISSET(msock,&rfds))
{
//int ssock;
ssock= accept(msock,(struct sockaddr *)&clientaddr,&client_len);
if(ssock<0)
{
cerr<<"Accept error";
}
FD_SET(ssock,&afds);
}
int n;
for(fd=0;fd<nfds;++fd)
if(fd!=msock && FD_ISSET (fd,&rfds))
while ( (n = recv(fd, buf, MAXLINE,0)) > 0) {
cout<<"String received from and resent to the client:"<<endl;
puts(buf);
send(fd, buf, n, 0);
}
close(fd);
FD_CLR(fd,&afds);
}
}
output::
client-hi
server-hi
client-bye
server-bye
//after some message exchange
client-wru?
server-wru?
client- i m here
server-i am here u?
You're making the usual mistake of ignoring the count returned by recv(). The data in the buffer is only valid up to that count. The rest of it is unchanged from its previous value.
You're also ignoring the possibility of an error in bind(), listen(), send(), and recv().