OpenSSL in C++ Socket Connection (HTTPS Client) - c++

i wrote an script, who can create an connection to an HTTP Server and shows the content of the website in the console.
Very easy.
But i want to connect to an https server and do the same procedures.
I searched at google and didn't found what i searched.
Please help me and give me an tutorial who can i use the openssl library.
I tried myself on the openssl library, but the library is very complicated and difficult to understand.
Here is my code of the http client:
#include <iostream>
#include <ctype.h>
#include <cstring>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <unistd.h>
#include <sstream>
#include <fstream>
#include <string>
#include <arpa/inet.h>
#include <openssl/ssl.h>
using namespace std;
int sock;
struct sockaddr_in client;
int PORT = 80;
int main(int argc, char const *argv[])
{
bzero(&client, sizeof(client));
client.sin_family = AF_INET;
client.sin_port = htons( PORT );
client.sin_addr.s_addr = inet_addr("172.16.0.6");
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
cout << "Error creating socket." << endl;
exit(1);
}
if ( connect(sock, (struct sockaddr *)&client, sizeof(client)) < 0 ) {
close(sock);
cout << "Could not connect" << endl;
exit(1);
}
stringstream ss;
ss << "GET /" << "\r\n"
<< "Host: 172.16.1.4\r\n"
<< "Accept: application/json\r\n"
<< "Connection: close"
<< "\r\n\r\n";
string request = ss.str();
if (send(sock, request.c_str(), request.length(), 0) != (int)request.length()) {
cout << "Error sending request." << endl;
exit(1);
}
char cur;
while ( read(sock, &cur, 1) > 0 ) {
cout << cur;
}
return 0;
}

Here is a sample SSL client that connects to https://about.google/intl/en/ and prints downloaded a page : SSLClient.cpp
//============================================================================
// Name : SSLClient.cpp
// Compiling : g++ -c -o SSLClient.o SSLClient.cpp
// g++ -o SSLClient SSLClient.o -lssl -lcrypto
//============================================================================
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <string.h>
using namespace std;
SSL *ssl;
int sock;
int RecvPacket()
{
int len=100;
char buf[1000000];
do {
len=SSL_read(ssl, buf, 100);
buf[len]=0;
printf("%s\n",buf);
// fprintf(fp, "%s",buf);
} while (len > 0);
if (len < 0) {
int err = SSL_get_error(ssl, len);
if (err == SSL_ERROR_WANT_READ)
return 0;
if (err == SSL_ERROR_WANT_WRITE)
return 0;
if (err == SSL_ERROR_ZERO_RETURN || err == SSL_ERROR_SYSCALL || err == SSL_ERROR_SSL)
return -1;
}
}
int SendPacket(const char *buf)
{
int len = SSL_write(ssl, buf, strlen(buf));
if (len < 0) {
int err = SSL_get_error(ssl, len);
switch (err) {
case SSL_ERROR_WANT_WRITE:
return 0;
case SSL_ERROR_WANT_READ:
return 0;
case SSL_ERROR_ZERO_RETURN:
case SSL_ERROR_SYSCALL:
case SSL_ERROR_SSL:
default:
return -1;
}
}
}
void log_ssl()
{
int err;
while (err = ERR_get_error()) {
char *str = ERR_error_string(err, 0);
if (!str)
return;
printf(str);
printf("\n");
fflush(stdout);
}
}
int main(int argc, char *argv[])
{
int s;
s = socket(AF_INET, SOCK_STREAM, 0);
if (s < 0) {
printf("Error creating socket.\n");
return -1;
}
struct sockaddr_in sa;
memset (&sa, 0, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = inet_addr("173.194.222.139"); // address of google.ru
sa.sin_port = htons (443);
socklen_t socklen = sizeof(sa);
if (connect(s, (struct sockaddr *)&sa, socklen)) {
printf("Error connecting to server.\n");
return -1;
}
SSL_library_init();
SSLeay_add_ssl_algorithms();
SSL_load_error_strings();
const SSL_METHOD *meth = TLSv1_2_client_method();
SSL_CTX *ctx = SSL_CTX_new (meth);
ssl = SSL_new (ctx);
if (!ssl) {
printf("Error creating SSL.\n");
log_ssl();
return -1;
}
sock = SSL_get_fd(ssl);
SSL_set_fd(ssl, s);
int err = SSL_connect(ssl);
if (err <= 0) {
printf("Error creating SSL connection. err=%x\n", err);
log_ssl();
fflush(stdout);
return -1;
}
printf ("SSL connection using %s\n", SSL_get_cipher (ssl));
char *request = "GET https://about.google/intl/en/ HTTP/1.1\r\n\r\n";
SendPacket(request);
RecvPacket();
return 0;
}
Note that if you want to exchange data between client and server with openssl, you might need to process error codes SSL_ERROR_WANT_READ and SSL_ERROR_WANT_WRITE as described in documentation. But it's not necessary here as HTTPS protocol is serial.

Related

UDP client can not recieve data from server in C++

I am new for C++. I tried to write a UDP client and server in C++. The server can receive data from client. But the client can not receive data from server. No matter what data the server sends, the method recvfrom in client always returns 0.
The client code is below:
#include <winsock2.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
#pragma comment(lib, "ws2_32.lib")
#define BUFFER_SIZE 1024
int main()
{
SOCKET sock_Client;
WSADATA WSAData;
char receBuf[BUFFER_SIZE];
char sendBuf[BUFFER_SIZE];
if (WSAStartup(MAKEWORD(2, 2), &WSAData) != 0)
{
printf("initialation fails!");
return -1;
}
sock_Client = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
SOCKADDR_IN addr_server;
addr_server.sin_family = AF_INET;
addr_server.sin_port = htons(4567);
addr_server.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
SOCKADDR_IN sock;
int len = sizeof(sock);
while (true)
{
cout << "input data to send:";
cin >> sendBuf;
sendto(sock_Client, sendBuf, strlen(sendBuf), 0, (SOCKADDR*)&addr_server, sizeof(SOCKADDR));
//int last=recv(sock_Client, receBuf, strlen(receBuf), 0); //
int last = recvfrom(sock_Client, receBuf, strlen(receBuf), 0, (SOCKADDR*)&sock, &len);
if (last > 0)
{
receBuf[last] = '\0';
if (strcmp(receBuf, "bye") == 0)
{
cout << "server stops talking..." << endl;
closesocket(sock_Client);
break;
}
else
{
printf("received data:%s\n", receBuf);
}
}
}
closesocket(sock_Client);
WSACleanup();
return 0;
}
The server code:
#include <winsock2.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
#pragma comment(lib, "ws2_32.lib")
#define BUFFER_SIZE 1024
int main()
{
WSADATA WSAData;
char receBuf[BUFFER_SIZE];
char Response[BUFFER_SIZE];
if (WSAStartup(MAKEWORD(2, 2), &WSAData) != 0)
{
printf("initialation fails!");
exit(1);
}
SOCKET sockServer = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sockServer == INVALID_SOCKET)
{
printf("Failed socket() \n");
return 0;
}
SOCKADDR_IN addr_Server;
addr_Server.sin_family = AF_INET;
addr_Server.sin_port = htons(4567);
addr_Server.sin_addr.S_un.S_addr = INADDR_ANY;
if (bind(sockServer, (SOCKADDR*)&addr_Server, sizeof(addr_Server)) == SOCKET_ERROR)
{
printf("Failed socket() %d \n", WSAGetLastError());
return 0;
}
SOCKADDR_IN addr_Clt;
int fromlen = sizeof(SOCKADDR);
while (true)
{
int last = recvfrom(sockServer, receBuf, 1024, 0, (SOCKADDR*)&addr_Clt, &fromlen);
if (last > 0)
{
receBuf[last] = '\0';
if (strcmp(receBuf, "bye") == 0)
{
cout << " client stop talking..." << endl;
closesocket(sockServer);
return 0;
}
else
{
printf("received data(%s):%s\n", inet_ntoa(addr_Clt.sin_addr), receBuf);
}
}
cout << "anser client:";//<br>Response = “”;
cin >> Response;
sendto(sockServer, Response, strlen(Response), 0, (SOCKADDR*)&addr_Clt, sizeof(SOCKADDR));
}
closesocket(sockServer);
WSACleanup();
return 0;
}
Anyone know what is wrong with the code?
The code runs in Windows. So, set(CMAKE_CXX_STANDARD 14) has to be added into CMakeLists.txt. If you want to run the code, please notice that.

cannot send nor receive data through sockets

I tried making a simple server-client socket communication but something seems to no work properly with the server. I get this error whenever I send or receive:
Socket operation on non-socket: Socket operation on non-socket
Strangely enough, this only appears whenever the server is sending.
the client seems to be ok:
//server
#include <iostream>
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <arpa/inet.h>
using namespace std;
int main(){
const int PORT = 5000;
int serverfd, clientfd, opt=1, n_send, n_recv;
sockaddr_in server_address, client_address;
char recvbuf[1024], sendbuf[1024];
bzero(&server_address , sizeof(server_address));
inet_pton(AF_INET, "127.0.0.1",&server_address.sin_addr);
int x = INADDR_ANY;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(PORT);
socklen_t addrSize = sizeof(server_address);
if((serverfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0){
perror(strerror(errno));
exit(EXIT_FAILURE);
}
if((setsockopt(serverfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) < 0){
perror(strerror(errno));
exit(EXIT_FAILURE);
}
if((bind(serverfd, (sockaddr*)&server_address, sizeof(server_address)))< 0){
perror(strerror(errno));
exit(EXIT_FAILURE);
}
if((listen(serverfd, 1))< 0){
perror(strerror(errno));
exit(EXIT_FAILURE);
}
if((clientfd = accept(serverfd, (sockaddr *)&server_address, (socklen_t*)&addrSize) < 0)){
perror(strerror(errno));
exit(EXIT_FAILURE);
}
while (true){
cout << "SAY TO CLIENT: ";
bzero(sendbuf, sizeof(sendbuf));
cin >> sendbuf;
cout << endl;
send(clientfd, sendbuf, strlen(sendbuf), 0);
errno = 0;
bzero(recvbuf, sizeof(recvbuf));
if((n_recv = recv(clientfd, recvbuf, sizeof(recvbuf), MSG_WAITALL))< 0){
perror(strerror(errno));
exit(EXIT_FAILURE);
}
cout << recvbuf << endl;
}
return 0;
}
//client
#include <iostream>
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <arpa/inet.h>
using namespace std;
int main(){
const int PORT = 5000;
int sockfd, n_send, n_recv;
char recvbuf[1024], sendbuf[1024];
sockaddr_in server_address;
bzero(&server_address, sizeof(server_address));
server_address.sin_family= AF_INET;
server_address.sin_port = htons(PORT);
inet_pton(AF_INET, "127.0.0.1", &server_address.sin_addr);
if((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0){
perror(strerror(errno));
exit(EXIT_FAILURE);
}
if(connect(sockfd, (sockaddr *) &server_address, sizeof(server_address))<0){
perror(strerror(errno));
exit(EXIT_FAILURE);
}
while (true){
if((n_recv = recv(sockfd, recvbuf, sizeof(recvbuf), MSG_WAITALL)) < 0){
perror(strerror(errno));
exit(EXIT_FAILURE);
}
cout << "Server: " << recvbuf << endl;
cout << "Say to server: ";
cin >> sendbuf;
cout << endl;
if((n_send = send(sockfd, sendbuf, sizeof(sendbuf), 0)) < 0){
perror(strerror(errno));
exit(EXIT_FAILURE);
}
}
return 0;
}
clientfd is assigned a non-socket value. If we change the whitespace in your if:
if((clientfd =
accept(serverfd, (sockaddr *)&server_address, (socklen_t*)&addrSize) < 0
)) {
perror(strerror(errno));
exit(EXIT_FAILURE);
}
Because of the way you wrote it, the result of accept (the presumably valid socket) is checked, and that result is set to clientFd. Note that your parenthesis placement doesn't match your other lines.

c++ socket timeout error when trying to connect

I've recently into c/c++ socket programming so I just made simple program that server and client respond each other. My server is in VMware( linux fedora) and client is windows(in visual studio 2017).
And it worked(pls notice that server and client are in one laptop)..
I also tried same client code with another computer(my deskTop) and got a WSAETIMEDOUT(10060)
error. The error was captured in connect() function in client code.
I have no idea how to solve :(
Could anybody help me?
Here's a client code
#include <iostream>
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <WinSock2.h>
using namespace std;
#define DEFAULT_BUFLEN 512
int main(int argc, char *argv[]) {
WSADATA wsaData;
SOCKET connectSocket;
SOCKADDR_IN servAddr;
char sendBuf[DEFAULT_BUFLEN];
char recvBuf[DEFAULT_BUFLEN];
char nickName[DEFAULT_BUFLEN];
int recvLen = 0;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
cout << "start up error";
exit(1);
}
connectSocket = socket(PF_INET, SOCK_STREAM, 0);
if (connectSocket == INVALID_SOCKET) {
cout << "socket creation error";
exit(1);
}
memset(&servAddr, 0, sizeof(servAddr));
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = inet_addr(argv[1]);
servAddr.sin_port = htons(atoi(argv[2]));
if (connect(connectSocket, (SOCKADDR*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR) {
cout << "connect error: " << WSAGetLastError();
exit(1);
}
while (1) {
recvLen = recv(connectSocket, recvBuf, sizeof(recvBuf), 0);
if (recvLen > 0) {
if (strcmp(recvBuf, "Exit") == 0)
break;
cout << recvBuf;
//cin >> nickName;
cin.getline(nickName, DEFAULT_BUFLEN);
send(connectSocket, nickName, sizeof(nickName),0);
}
else if (recvLen == 0)
cout << "Connection closed";
else if (recvLen == -1)
cout << "Connection failed";
}
closesocket(connectSocket);
WSACleanup();
return 0;
}
Blockquote
and server code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <iostream>
#include <string>
#define DEFAULT_LEN 512
#define DEFAULT_CLIENT_NUM 30
using namespace std;
char nickNameCommand[]="Please set your nickName:";
void error_handling(char * message);
class Client {
private:
char nickName[DEFAULT_LEN];
int clientSock;
public:
struct sockaddr_in clnt_addr;
int& getClientSock(){
return clientSock;
}
};
class Server {
private:
int serv_sock;
char informClientNickName[DEFAULT_LEN] = "Your NickName is ";
public:
Server(){
}
char message[DEFAULT_LEN]= "";
char clientNickName[DEFAULT_CLIENT_NUM][DEFAULT_LEN];
struct sockaddr_in serv_addr;
void setServSock(int value){
serv_sock = value;
}
int getServSock(){
return serv_sock;
}
void setInformClientNickName(int clientNum){
strcat(informClientNickName,clientNickName[clientNum]);
strcat(message , informClientNickName);
}
char* getInformClientNickName(){
return informClientNickName;
}
};
int main(int argc,char * argv[])
{
Client clientSocket[DEFAULT_CLIENT_NUM];
Server server;
int clientNum=0;
int recvLen=0;
socklen_t clnt_addr_size;
char message[DEFAULT_LEN];
if(argc!=2)
{
printf("Usage: %s <port>\n",argv[0]);
exit(1);
}
server.setServSock(socket(PF_INET,SOCK_STREAM,0));
if(server.getServSock() == -1)
error_handling("socket() error");
memset(&(server.serv_addr),0,sizeof(server.serv_addr));
server.serv_addr.sin_family=AF_INET;
server.serv_addr.sin_addr.s_addr=htonl(INADDR_ANY);
server.serv_addr.sin_port=htons(atoi(argv[1]));
if(bind(server.getServSock(),(struct sockaddr*)&
(server.serv_addr),sizeof(server.serv_addr)) ==-1)
error_handling("bind() error");
if(listen(server.getServSock(),5)==-1)
error_handling("listen() error");
clnt_addr_size=sizeof(clientSocket[0].clnt_addr);
while(1) {
clientSocket[clientNum].getClientSock() = accept(server.getServSock(),
(struct sockaddr*)&(clientSocket[clientNum].clnt_addr),&clnt_addr_size);
if(clientSocket[clientNum].getClientSock()==-1)
error_handling("accept() error");
else{
write(clientSocket[clientNum].getClientSock(),nickNameCommand,sizeof(nickNameCommand));
read(clientSocket[clientNum].getClientSock(),(void*)(server.clientNickName[clientNum]),DEFAULT_LEN);
}
cout << "Received name is : " << server.clientNickName[clientNum]<<endl;
clientNum++;
cout << "ClientNum: " << clientNum <<endl;
recvLen=0;
for(int i=0;i<clientNum;i++){
server.setInformClientNickName(i);
write(clientSocket[clientNum].getClientSock(),server.message,sizeof(server.message));
}
}
for(int i=0;i<clientNum;i++)
close(clientSocket[i].getClientSock());
close(server.getServSock());
return 0;
}
void error_handling(char * message)
{
fputs(message,stderr);
fputc('\n',stderr);
exit(1);
}

Multiple Broadcast Reception on Same port but different interfaces

I'm trying to build a little personal DHCP server to serve a specific scope if the broadcast is received on eth0 and another if received on wlan0 but I can't bind more than a single interface on the same address:port combination (255.255.255.255:67)
I heard about SO_REUSABLE but I have no idea about how to implement it and if of course it's the good way to do it
Actually this is my code :
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <errno.h>
#include <fstream>
#include <iostream>
#include <vector>
#define BUFLEN 1024
#define PORT 67
using namespace std;
char *ipAddrFromInterface(char *apInterfaceName) //this function is not from me
{
return "255.255.255.255";
/*char *if_name = (char *) apInterfaceName;
struct ifreq ifr;
size_t if_name_len = strlen(if_name);
if(if_name_len < sizeof(ifr.ifr_name))
{
memcpy(ifr.ifr_name, if_name, if_name_len);
ifr.ifr_name[if_name_len] = 0;
}
else
printf("interface name is too long\n");
int fd = socket(AF_INET, SOCK_DGRAM, 0);
if(fd == -1)
printf("A => %s\n", strerror(errno));
if(ioctl(fd, SIOCGIFADDR, &ifr) == -1)
{
int temp_errno = errno;
close(fd);
printf("B => %s\n", strerror(temp_errno));
}
if(ioctl(fd, SIOCGIFADDR, &ifr) == -1)
{
int temp_errno = errno;
close(fd);
printf("C => %s\n", strerror(temp_errno));
}
close(fd);
struct sockaddr_in* ipaddr = (struct sockaddr_in*) &ifr.ifr_addr;
return inet_ntoa(ipaddr->sin_addr);*/
}
struct socketData
{
int sock;
sockaddr_in socket;
char *interfaceName;
};
void print(int i)
{
printf("%d\n", i);
fflush(stdout);
}
void server_receive_thread(vector<char*> aInterfaceList)
{
int socketIndex = 0;
struct sockaddr_in localSock;
int socketDescriptor; int socketLength;
vector<socketData> aSockets;
for( ; socketIndex < aInterfaceList.size(); socketIndex++)
{
socketData socketD;
char *apInterfaceName = aInterfaceList.at(socketIndex);
if((socketDescriptor = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
{
printf("can't listen on interface %s... sleeping\n", apInterfaceName);
}
else
{
memset(&localSock, 0, sizeof(localSock));
localSock.sin_family = AF_INET;
localSock.sin_port = htons(PORT);
inet_aton(ipAddrFromInterface(apInterfaceName), &localSock.sin_addr);
setsockopt(socketDescriptor, SOL_SOCKET, SO_BINDTODEVICE, apInterfaceName, sizeof(apInterfaceName));
if(bind(socketDescriptor, (struct sockaddr *) &localSock, sizeof(localSock)) == -1)
{
printf("can't bind interface %s to listen on port %d... sleeping\n", apInterfaceName, PORT);
}
else
{
printf("bound to interface %s on port %d\n", apInterfaceName, PORT);
socketD.sock = socketDescriptor;
socketD.socket = localSock;
socketD.interfaceName = apInterfaceName;
aSockets.push_back(socketD);
}
}
}
fd_set master;
int fdMax = -1;
while(1)
{
FD_ZERO(&master);
for(int iSock = 0; iSock < aSockets.size(); iSock++)
{
socketData d = aSockets.at(iSock);
FD_SET(d.sock, &master);
if(d.sock > fdMax)
fdMax = d.sock;
}
printf("fdmax is : ");
print(fdMax);
if(select(fdMax + 1, &master, NULL, NULL, NULL) == -1)
print(2);
print(200);
for(int iSock = 0; iSock < aSockets.size(); iSock++)
{
socketData d = aSockets.at(iSock);
if(FD_ISSET(d.sock, &master))
print(3);
}
print(1);
}
}
int main()
{
std::vector<char*> interfaceList;
interfaceList.push_back("wlan0");
interfaceList.push_back("eth0");
server_receive_thread(interfaceList);
return 0;
}
You don't need a socket per interface. Just bind a single socket to 0.0.0.0 and the desired port. Then it will receive via all interfaces. You certainly can't, and don't need to, bind to 255.255.255.255.
Or, bind it to the single IP address that is connected to the scope you want to serve.

socket programming( server and client on the same computer) something wrong with connection

I'm new to socket programming and I have this client that tries to connect to a server on the same computer. But the server hangs there after bind or accept—cause bind seems to be right but no output. I know that the server works because another client can connect just fine and the client seems to have done that. What causes the server to not see this incoming connection? I'm at the end of my wits here.
And I haven't been used to programming on Mac, so thank you so much for your patience if I have made some foolish mistakes.
My code is as follows:
server.cpp
using namespace std;
#include<iostream>
#include <netinet/in.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#define PORT 8888
#define BACKLOG 20
//#define DEST_IP "127.0.0.1"
int process_conn_server(int s)
{
ssize_t size =0;
char buffer[1024];
for( ; ; )
{
size = read(s,buffer,1024);
if(size == 0)
{
return 0;
}
}
sprintf(buffer, "%d bytes altogether\n", (int)size);
write(s, buffer,strlen(buffer)+1);
return 0;
}
int main(int argc,char *argv[])
{
//cout<<"?";
int ss, sc, r, err;
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
int opt=1;
pid_t pid;
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(PORT);
ss = socket(AF_INET, SOCK_STREAM, 0);
if(ss<0)
{
cout<<"[process infro]socket error"<<endl;
return -1;
}
cout<<"[process infro]socket successful"<<endl;
r = setsockopt(ss, SOL_SOCKET,SO_REUSEADDR, (void*)&opt,sizeof(opt));
if (r == -1)
{
perror("setsockopt(listen)");
return 0;
}
cout<<"[process infro]sockopt successful"<<endl;
cout<<"?";
err = bind(ss, (struct sockaddr*) &server_addr, sizeof( server_addr));
cout<<"err";
if(err < 0)
{
cout<<"[process infro]bind error"<<endl;
return -1;
}
cout<<"[process infro]bind successful";
err=listen(ss, BACKLOG);
if(err <0)
{
cout<<"[process infro]listen error"<<endl;
return -1;
}
cout<<"[process infro]lisen successful";
for( ; ; )
{
int addrlen = sizeof(struct sockaddr);
sc = accept(ss, (struct sockaddr*)&client_addr, (socklen_t *)&addrlen);
if(sc < 0)
{
continue;
}
pid = fork();
if (pid == 0)
{
close(ss);
process_conn_server(sc);
}
else
{
close(sc);
}
}
//opt=0;
//setsockopt(ss,SOL_SOCKET,SO_REUSEADDR,(void*)&opt,sizeof(len));
}
client.cpp
using namespace std;
#include<iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <time.h>
#include <arpa/inet.h>
#include <fstream.h>
#define PORT 8888
#define DEST_IP "127.0.0.1"
void process_conn_client(int s)
{
ssize_t size = 0;
char buffer[1024];
//read from the file to be sent
fstream outfile("programm.txt",ios::in|ios::out);
if (outfile.fail())
{
printf("[process infro]cannot open the file to be sent\n");
return ;
}
printf("[process infro]successfully open the file to be sent\n");
while(!outfile.eof())
{
outfile.getline(buffer,1025,'\n');
write(s,buffer,1024);
size = read(s, buffer, 1024);
if(size = 0)
{
return ;
}
//write to the server
write(s,buffer,size);
//get response from the server
size=read(s,buffer,1024);
write(1,buffer,size);
}
outfile.close(); //关闭文件
}
int main(int argc,char *argv[])
{
int s;
struct sockaddr_in server_addr;
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(DEST_IP);
server_addr.sin_port = htons(PORT);
s = socket(AF_INET, SOCK_STREAM, 0);
if(s < 0)
{
cout<<"[process infro]socke error"<<endl;
return -1;
}
cout<<"[process infro] socket built successfully\n";
//inet_pton(AF_INET, argv[1], &server_addr.sin_addr);
connect(s, (struct sockaddr*)&server_addr, sizeof(struct sockaddr));
cout<<"[process infor] connected\n";
process_conn_client(s);
close(s);
return 0;
}
This may be unrelated.... but it won't fit in a comment...
In your server you do this:
int process_conn_server(int s)
{
ssize_t size =0;
char buffer[1024];
for( ; ; )
{
// keep reading until read returns 0
size = read(s,buffer,1024);
if(size == 0)
{
return 0;
}
}
sprintf(buffer, "%d bytes altogether\n", (int)size);
write(s, buffer,strlen(buffer)+1);
return 0;
}
In your client you do this:
void process_conn_client(int s)
{
ssize_t size = 0;
char buffer[1024];
//read from the file to be sent
fstream outfile("programm.txt",ios::in|ios::out);
if (outfile.fail())
{
printf("[process infro]cannot open the file to be sent\n");
return ;
}
printf("[process infro]successfully open the file to be sent\n");
while(!outfile.eof())
{
outfile.getline(buffer,1025,'\n');
// write to server?
write(s,buffer,1024);
// read from server?
size = read(s, buffer, 1024);
if(size = 0)
{
return ;
}
//write to the server
write(s,buffer,size);
//get response from the server
size=read(s,buffer,1024);
write(1,buffer,size);
}
outfile.close();
}
It's a bit hard to follow because of your variable names, but it looks like your client is working under the assumption that your server will send back a response for every chunk of data received, which isn't the case. You server doesn't appear to have changed the accepted socket to non-blocking, so it's going to block on the read call until there is some data to read (it's never going to get 0)...
Are you sure it's failing before this point? Do you have some sample output?
Aso, in your call to accept, you pass addrlen...
int addrlen = sizeof(struct sockaddr);
I think this should be:
int addrlen = sizeof(struct sockaddr_in); /* sizeof(client_addr) */