make a https get request in linux based on openssl - c

guys.
I want to create a https get request on linux with openssl. I made the code from google and my mind. after i run the code,there is something happened, i think the RecvPacket() function has problem,but i do not know how to fix, please tell me how to fix it.
the website where i want to get is https://git.20202060.xyz.it just has a jpg file,what i want to do is download the picture to local file,but now i even can not get the https response,the i could not cut the picture out.
here is code.
SSL *ssl;
int sock;
int RecvPacket()
{
int len = 1024;
char buf[100000] = {'\0'};
if (SSL_read(ssl, buf, 1024) > 0)
{
printf("Receiving . . . .\n");
while (len = 1024)
{
// len = SSL_read(ssl, buf, 1024);
len = SSL_read(ssl, buf, 1024);
buf[len] = '\0';
printf("%s", buf);
if (len < 0)
{
break;
}
}
}
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, sizeof(buf));
if (len > 0)
{
fprintf(stderr, "Writing . . . . \n");
}
if (len < 0)
{
int err = SSL_get_error(ssl, len);
switch (err)
{
case SSL_ERROR_WANT_WRITE:
printf("SSL_ERROR_WANT_WRITE\n");
return 0;
case SSL_ERROR_WANT_READ:
printf("SSL_ERROR_WANT_READ\n");
return 0;
case SSL_ERROR_ZERO_RETURN:
printf("SSL_ERROR_ZERO_RETURN\n");
case SSL_ERROR_SYSCALL:
printf("SSL_ERROR_SYSCALL\n");
case SSL_ERROR_SSL:
printf("SSL_ERROR_SSL\n");
default:
return -1;
}
}
}
int main(int argc, char *argv[])
{
int sockfd;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 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("119.28.113.108"); // address of 20202060.xyz
sa.sin_port = htons(443);
socklen_t socklen = sizeof(sa);
if (connect(sockfd, (struct sockaddr *)&sa, socklen))
{
printf("Error connecting to server.\n");
return -1;
}
//openssl initialize
SSL_library_init();
SSLeay_add_ssl_algorithms();
SSL_load_error_strings();
SSL_CTX *ctx = SSL_CTX_new(SSLv23_client_method());
ssl = SSL_new(ctx);
if (!ssl)
{
printf("Error creating SSL.\n");
log_ssl();
return -1;
}
//creat an ssl connection and attach it to the socket
sock = SSL_get_fd(ssl);
SSL_set_fd(ssl, sockfd);
SSL_set_connect_state(ssl);
int err = SSL_connect(ssl);
if (err != 1)
{
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[1024] = {'\0'};
// char *request_test = "Get /dog.jpg HTTP/1.1\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT)\r\nHost:https://20202060.xyz\r\nConnection: Close\r\n";
char host[100] = "https://git.20202060.xyz";
// char ip[30] = "119.28.113.108";
sprintf(request,
"GET /dog.jpg HTTP/1.1\r\n"
"Host: %s\r\n"
"Accept: */*\r\n"
"User-Agent:Mozilla/5.0\r\n"
"Connection: Close\r\n",
host);
SendPacket(request);
RecvPacket();
SSL_shutdown(ssl);
SSL_free(ssl);
close(sockfd);
return 0;
}

Related

Nothing read after SSL_handshake

I try to make a SSL connection, until the SSL_handshake. After the handshake, there is nothing to read from the socket. There is something written to the socket from the client so I expect a response of the server. The socket is connected the whole process, so I don't know what's wrong. The code is displayed under and I have placed comments where the process fails.
struct ssl_information {
int connected;
int sock;
BIO *bio_read;
BIO *bio_write;
SSL *ssl;
SSL_CTX *ctx;
};
void ssl_connection_init()
{
SSL_load_error_strings();
SSL_library_init();
OpenSSL_add_all_algorithms();
}
void ssl_disconnect(struct ssl_information *ssl)
{
if(!ssl->connected) return;
if(ssl->ctx) SSL_CTX_free(ssl->ctx);
if(ssl->ssl) {
SSL_shutdown(ssl->ssl);
SSL_free(ssl->ssl);
}
close(ssl->sock);
ssl->connected = 0;
}
int ssl_read_socket(struct ssl_information *ssl)
{
int rc;
unsigned char buffer[4096];
rc = read(ssl->sock, buffer, sizeof(buffer)); \\reads nothing on the last call
if(rc == 0 || rc == -1) return 0;
BIO_write(ssl->bio_read, buffer, rc);
return 1;
}
int ssl_write_socket(struct ssl_information *ssl)
{
int rc;
unsigned char buffer[4096];
rc = BIO_read(ssl->bio_write, buffer, sizeof(buffer));
if(write(ssl->sock, buffer, rc) != rc) return 0;
return 1;
}
int tcp_connection(char *ip, int port)
{
int flags, rc, sock;
struct sockaddr_in address;
sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock == -1) return -1;
flags = fcntl(sock, F_GETFL);
rc = fcntl(sock, F_SETFL, flags | O_NONBLOCK);
memset(&address, 0, sizeof(address));
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr(ip);
address.sin_port = htons(port);
connect(sock, (struct sockaddr *)&address, sizeof(address));
return sock;
}
struct ssl_information ssl_connection(char *ip, int port)
{
fd_set read_file_descriptor, write_file_descriptor;
static struct ssl_information ssl;
ssl.sock = tcp_connection(ip, port);
if(ssl.sock == -1) {
ssl.connected = 0;
return ssl;
}
ssl.bio_read = BIO_new(BIO_s_mem());
ssl.bio_write = BIO_new(BIO_s_mem());
ssl.ctx = SSL_CTX_new(TLS_method());
ssl.ssl = SSL_new(ssl.ctx);
SSL_set_connect_state(ssl.ssl);
SSL_set_bio(ssl.ssl, ssl.bio_read, ssl.bio_write);
while(1) {
FD_ZERO(&read_file_descriptor);
FD_ZERO(&write_file_descriptor);
if(SSL_in_init(ssl.ssl)) SSL_do_handshake(ssl.ssl);
if(SSL_is_init_finished(ssl.ssl)) break;
FD_SET(ssl.sock, &read_file_descriptor);
if(BIO_pending(ssl.bio_write)) FD_SET(ssl.sock, &write_file_descriptor);
switch(select(FD_SETSIZE, &read_file_descriptor, &write_file_descriptor, 0, 0)) {
case -1:
case 0:
printf("Failed to monitor socket!\n");
ssl_disconnect(&ssl);
return ssl;
default:
if(FD_ISSET(ssl.sock, &read_file_descriptor)) {
if(!ssl_read_socket(&ssl)) {
printf("Failed to read from socket!\n");
ssl_disconnect(&ssl);
return ssl;
}
}
if(FD_ISSET(ssl.sock, &write_file_descriptor)) {
if(!ssl_write_socket(&ssl)) {
printf("Failed to write to socket!\n");
ssl_disconnect(&ssl);
return ssl;
}
}
}
}
ssl.connected = 1;
return ssl;
}
int main()
{
struct ssl_information ssl;
char response[4096];
ssl = ssl_connection(ip, port);
if(!ssl.connected) {
ssl_disconnect(&ssl);
return 0;
}
BIO_write(ssl.bio_write, message, sizeof(message)); //message is of course set to something
ssl_write_socket(&ssl);
ssl_read_socket(&ssl); \\returns 0
BIO_read(ssl.bio_read, response, sizeof(response)); \\ reads nothing
printf("response: %s\n", response);
return 1;
}

UDP winsock chat program receives -1 from recvfrom() and sendto()

Currently, we are producing UDP chat programs using MFC and C.
I'm working on both bind because I have to send incoming messages from the server and client.
An error occurs when recvfrom() and sendto(), they return -1.
I don't know what the problem is. I searched it and did what I did, but it's not working.
Why does sendto() and recvfrom() return -1?
I don't know what the problem is.
server Code
static UINT UdpServerFunc(LPVOID pVoid)
{
CServerDlg *dlg = (CServerDlg *)AfxGetApp()->m_pMainWnd;
//------------------------------------------------------
CString slniPath;
slniPath.Format(_T("./NetworkPath.ini"));
TCHAR ServerPort[MAX_PATH];
int ServerPort_Num;
GetPrivateProfileString(_T("ServerInfo"), _T("Port"), _T(""), ServerPort, MAX_PATH, slniPath);
ServerPort_Num = _ttoi(ServerPort);
//------------------------------------------------------
//Startup Winsock
WSADATA wsaData;
int retval = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (retval != 0)
{
AfxMessageBox("WSAStartup() Error\n");
return 0;
}
//SOCKET
dlg->server_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);//IPPROTO_UDP or PPROTO_HOPOPTS
if (dlg->server_sock == SOCKET_ERROR)
{
AfxMessageBox("Socket() Error\n");
return 0;
}
ZeroMemory(&dlg->server_addr, sizeof(dlg-> server_addr));
dlg->server_addr.sin_family = AF_INET;
dlg->server_addr.sin_port = htons(ServerPort_Num); //30112
dlg->server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
dlg->client_addr.sin_family = AF_INET;
dlg->client_addr.sin_port = htons(ServerPort_Num);
dlg->client_addr.sin_addr.s_addr = htonl(INADDR_ANY);
retval = bind(dlg->server_sock, (SOCKADDR*)&dlg->server_addr, sizeof(dlg->server_addr));
AfxMessageBox("server start");
if (retval == SOCKET_ERROR) {
AfxMessageBox("bind() ERROR\n");
return -1;
}
//Data Communication
int addrlength;
char buf[BUFFER_SIZE];
int recv_size;
while (1)
{
//recvfrom()
addrlength = sizeof(dlg->client_addr);
recv_size = recvfrom(dlg->server_sock, reinterpret_cast<char*>(buf), BUFFER_SIZE, 0, (SOCKADDR*)&dlg->client_addr, &addrlength);
if (recv_size == SOCKET_ERROR)
{
AfxMessageBox("recvfrom() Error");
break;
}
//Data print
buf[recv_size] = '\0';
CString strMsg;
strMsg = CString(buf, recv_size);
dlg->m_ListChat.AddString(strMsg);
strMsg = "";
}
closesocket(dlg->server_sock);
WSACleanup;
}
Server Sendto Code
void CServerDlg::OnBnClickedButton2()
{
CServerDlg *dlg = (CServerDlg *)AfxGetApp()->m_pMainWnd;
CString strText = _T("");
char Text[BUFFER_SIZE];
dlg->m_edit_chat.GetWindowText(strText);
strcpy(Text, strText);
int send_size = sendto(dlg->server_sock, Text, strlen(Text), 0, (sockaddr*)&dlg->client_addr, sizeof(dlg->client_addr));
if (send_size == SOCKET_ERROR)
{
AfxMessageBox("sendto() Error");
}
else
{
dlg->m_ListChat.AddString(strText);
}
}
Client Code
static UINT ClientUdpThreadFunc(LPVOID pVOID) {
CClientTestDlg *dlg = (CClientTestDlg *)AfxGetApp()->m_pMainWnd;
CString slniPath;
slniPath.Format(_T("./NetworkPath.ini"));
TCHAR ServerPort[MAX_PATH];
int ServerPort_Num;
GetPrivateProfileString(_T("ServerInfo"), _T("Port"), _T(""), ServerPort, MAX_PATH, slniPath);
ServerPort_Num = _ttoi(ServerPort); //30112
TCHAR ServerIp[MAX_PATH];
int ServerIp_Num;
GetPrivateProfileString(_T("ServerInfo"), _T("IP"), _T(""), ServerIp, MAX_PATH, slniPath);
ServerIp_Num = _ttoi(ServerIp); //127.0.0.1
//--------------------------------------------------
//StartUp Winsock
WSADATA wsaData;
int retval = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (retval != 0)
{
AfxMessageBox("WSAStartup() Error\n");
return 0;
}
//socket
dlg->clnt_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (dlg->clnt_sock == SOCKET_ERROR) {
AfxMessageBox(_T("socket() Error"));
return 0;
}
ZeroMemory(&dlg->ServerAddr, sizeof(dlg->ServerAddr));
dlg->ServerAddr.sin_family = AF_INET;
dlg->ServerAddr.sin_port = htons(ServerPort_Num);
dlg->ServerAddr.sin_addr.s_addr = inet_addr(SERVERIP);
/*
dlg->FromServer.sin_family = AF_INET;
dlg->FromServer.sin_port = htons(ServerPort_Num);
dlg->FromServer.sin_addr.s_addr = inet_addr(SERVERIP);
*/
retval = bind(dlg->clnt_sock, (SOCKADDR*)&dlg->ServerAddr, sizeof(dlg->ServerAddr));
if (retval == SOCKET_ERROR) {
AfxMessageBox("bind() ERROR\n");
return -1;
}
//Data Communication
CString strMsg;
int addrlength;
char buf[BUF_SIZE];
int recv_size;
while (1) {
addrlength = sizeof(dlg->FromServer);
recv_size = recvfrom(dlg->clnt_sock, reinterpret_cast<char*>(buf), BUF_SIZE, 0, (sockaddr*)&dlg->FromServer, &addrlength);
if (recv_size == SOCKET_ERROR)
{
AfxMessageBox("recvfrom() ERROR");
break;
}
else
{
//Data print
buf[recv_size] = '\0';
strMsg = CString(buf, recv_size);
dlg->m_listChat.AddString(strMsg);
strMsg = "";
}
}
closesocket(dlg->clnt_sock);
WSACleanup;
}
Client Sendto Code
void CClientTestDlg::OnBnClickedButtonSend()
{
CClientTestDlg *dlg = (CClientTestDlg *)AfxGetApp()->m_pMainWnd;
CString UdpStrText = _T("");
char Text[BUF_SIZE];
m_editChat.GetWindowText(UdpStrText);
strcpy(Text, UdpStrText);
int UdpRtn;
UdpRtn = sendto(dlg->clnt_sock, Text, strlen(Text), 0, (SOCKADDR*)&dlg->ServerAddr, sizeof(dlg->ServerAddr));
if (UdpRtn == SOCKET_ERROR)
{
AfxMessageBox("sendto() ERROR\n %s");
}
closesocket(dlg->clnt_sock);
}

Create HTTP GET in C return 301 redirect using IP address

I want to send a GET request to a page and retrieve it to use later to a crawler
I have implemented my own D.N.S. resolver (like DIG command in LINUX) and I want to use the ip address to get the http page
I have the following code
typedef struct http_request
{
request_type req_type;
char* ip;
int port_number;
char* path;
char* data;
char* hostname;
}http_request;
typedef struct http_response
{
char* raw_response;
int status_code;
char* status_text;
char* body;
char* server_name;
int content_length;
char* content_type;
}http_response;
// main method
http_response* send_http_request(http_request* request) {
if (request == NULL) {
printf("HTTP request is NULL.\n");
return NULL;
}
http_response* response = (http_response*) malloc(sizeof(http_response));
if (response == NULL) {
exit(1);
return NULL;
}
char http_request_buffer[REQUEST_BUFF_SIZE];
memset(http_request_buffer, 0, REQUEST_BUFF_SIZE);
sprintf(http_request_buffer, "GET /%s HTTP/1.1\r\nHost:%s\r\n\r\n",
request->path, request->ip);
process_http_request(request, http_request_buffer, response);
return response;
}
static int process_http_request(http_request* request,
char* http_request_buffer, http_response* response) {
int socketfd;
struct sockaddr_in socket_details;
char temp_buffer[TEMP_BUFF_SIZE];
char* http_response_buffer;
ssize_t bytes_sent = 0;
ssize_t total_bytes_sent = 0;
ssize_t bytes_received = 0;
ssize_t total_bytes_received = 0;
int status;
http_response_buffer = (char*) malloc(RESPONSE_BUFF_SIZE);
if (http_response_buffer == NULL) {
printf(
"process_http_request: memory allocation failed for response buffer.\n");
return HTTP_ERROR_MEM_ALLOC_FAILED;
}
memset(http_response_buffer, 0, RESPONSE_BUFF_SIZE);
socketfd = socket(AF_INET, SOCK_STREAM, 0);
if (socketfd == -1) {
printf("process_http_request: socket creation failed.\n");
return HTTP_ERROR_SOCKET_CREATION_FAILED;
}
struct timeval timeout;
timeout.tv_sec = 5;
timeout.tv_usec = 0;
if (setsockopt(socketfd, SOL_SOCKET, SO_RCVTIMEO, (char *) &timeout,
sizeof(timeout)) < 0)
printf("process_http_request: socket option setting failed.\n");
bzero(&socket_details, sizeof(socket_details));
socket_details.sin_family = AF_INET;
socket_details.sin_addr.s_addr = inet_addr(request->ip);
socket_details.sin_port = htons(request->port_number);
if (connect(socketfd, (struct sockaddr*) &socket_details,
sizeof(struct sockaddr)) == -1) {
printf("process_http_request: Could not connect to the server.\n");
return HTTP_ERROR_SERVER_CONN_FAILED;
}
while (1) {
bytes_sent = send(socketfd, http_request_buffer,
strlen(http_request_buffer), 0);
if (bytes_sent < 0) {
printf("process_http_request: error writing on socket\n");
close(socketfd);
return HTTP_ERROR_SOCKET_WRITE_FAILED;
} else {
printf(
"process_http_request: wrote %d bytes data on socket successfully.\n",
(int) bytes_sent);
}
total_bytes_sent += (int) bytes_sent;
printf("process_http_request: total bytes sent = %d\n",
(int) total_bytes_sent);
if (total_bytes_sent == strlen(http_request_buffer))
break;
}
while (1) {
printf("process_http_request: receiving bytes from server\n");
memset(temp_buffer, 0, TEMP_BUFF_SIZE);
bytes_received = recv(socketfd, temp_buffer, TEMP_BUFF_SIZE, 0);
if (bytes_received == -1) {
if (total_bytes_received == 0) {
printf(
"process_http_request: Data could not be received from socket.\n");
close(socketfd);
return HTTP_ERROR_REC_FAILED;
} else {
printf(
"process_http_request: Timeout waiting for more data.\n");
break;
}
} else if (bytes_received > 0) {
sprintf(http_response_buffer, "%s%s", http_response_buffer,
temp_buffer);
total_bytes_received += bytes_received;
printf("process_http_request: total bytes received = %d\n",
(int) total_bytes_received);
}
if (bytes_received == 0) {
printf("process_http_request: Data receiving finished.\n");
close(socketfd);
break;
}
}
printf("raw buffer=%s", http_response_buffer);
response->raw_response = http_response_buffer;
status = process_http_response(http_response_buffer, response);
if (status == SUCCESS)
printf("process_http_request: HTTP response parsed successfully.\n");
else
printf(
"process_http_request: HTTP response parsing encountered problem. \n");
return status;
}
The problem is that in almost all cases return me a page with 301 redirect and a link .For example for google's ip return me a redirect page to http://www.google.com/ , and I want the page itself and I don't know what to do.
Someone please help.Thank you!

Socket Programming Send / Recv Before Scanf

Im trying to create connection between 2 clients via a server. In this program, client sends a message to the server and server post it to the target client. But there is a little problem between this operation. Transmitter one cannot send another message before it receive some message or receiver one cannot see the received message before send a message. Video should explain better.
You can find scanf function in below of client.c codes
CLIENT
//
// Created by berkin on 18.12.2016.
//
#include<stdio.h>
#include<sys/socket.h>
#include<arpa/inet.h> // for inet_addr
#include <string.h>
#include <zconf.h>
int main(int argc, char *argv[]) {
int sock;
struct sockaddr_in server;
char message[2000], server_reply[2000];
//Create socket
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == -1) {
printf("Could not create socket");
}
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons(8888);
//Connect to remote server
if (connect(sock, (struct sockaddr *) &server, sizeof(server)) < 0) {
perror("Connect failed. Error");
return 1;
}
puts("Connected to server\n");
//keep communicating with server
while (1) {
printf("> ");
scanf("%[^\n]%*c", message);
fflush(stdin);
//Send some data
if (send(sock, message, strlen(message)+1, 0) < 0) {
puts("Send failed");
return 1;
}
if (recv(sock, server_reply, 2000, 0) < 0) {
puts("recv failed");
break;
}
//Receive a reply from the server
printf ("\033[32;1m %s \033[0m\n",server_reply);
}
close(sock);
return 0;
}
SERVER
#include<stdio.h>
#include<string.h> // for strlen
#include<stdlib.h>
#include<sys/socket.h>
#include<arpa/inet.h> // for inet_addr
#include<unistd.h> // for write
#include<pthread.h> // for threading, link with lpthread
#include "split.h"
#define MAX_CLIENT_NUMBER 100
void *connection_handler(void *);
struct User {
char userName[10];
int clientSocketNo;
};
unsigned int clientNumber = 0;
unsigned int userArrayIndex = 0;
struct User users[MAX_CLIENT_NUMBER];
//FOR GETUSERS COMMAND
void getUsers(int socketNumber) {
char *userString = malloc(100);
if (users[0].userName != NULL) {
strcpy(userString, users[0].userName);
strcat(userString, ",");
} else {
return;
}
for (int i = 1; i < userArrayIndex; ++i) {
strcat(userString, users[i].userName);
strcat(userString, ",");
}
write(socketNumber, userString, strlen(userString) + 1);
}
//AFTER LOGIN COMMAND, ADD TO THE ARRAY
void addUserToArray(char userName[10], int socketNumber) {
printf("Client logged in as %s\n", userName);
strcpy(users[userArrayIndex].userName, userName);
users[userArrayIndex].clientSocketNo = socketNumber;
userArrayIndex++;
}
//LOGIN COMMAND
void loginUser(char userName[10], int socketNumber) {
char *message = "login successful";
write(socketNumber, message, strlen(message) + 1);
addUserToArray(userName, socketNumber);
}
//SEND MESSAGE IF USER FOUND
void sendMessage(struct User user, char *message){
write(user.clientSocketNo,message,strlen(message) + 1);
}
//SEARCH USER FROM ARRAY
struct User searchUser(char searchName[10]){
for (int i = 0; i < userArrayIndex; ++i) {
if(strcmp(users[i].userName,searchName) == 0){
return users[i];
}
}
}
void *connection_handler(void *socket_desc) {
//Get the socket descriptor
char receivedMessage[2000]; //client's message
int readControl;
int parsedItemNumber = 0;
int sock = *((int *) socket_desc);
while ((readControl = recv(sock, receivedMessage, 2000, 0)) > 0) {
char *parsedCommand[50]; //parsedClientMessage
parsedItemNumber = parsing(parsedCommand, receivedMessage, " ");
if (strcmp(parsedCommand[0], "login") == 0) {
loginUser(parsedCommand[1], sock);
}
else if (strcmp(parsedCommand[0], "getusers") == 0) {
getUsers(sock);
}
else if (strcmp(parsedCommand[0], "exit") == 0) {
close(sock);
return 0;
}
else{
if(parsedCommand[0] != NULL){
struct User find = searchUser(parsedCommand[0]);
if(find.userName != NULL){
char *message = malloc(2000);
if(parsedCommand[1] != NULL){
strcpy(message,parsedCommand[1]);
strcat(message," ");
}
for (int i = 2; i < parsedItemNumber; ++i) {
strcat(message,parsedCommand[i]);
strcat(message," ");
}
sendMessage(find,message);
}
else{
perror("Your input was wrong");
}
}
}
}
if (readControl == 0) {
puts("Client disconnected");
clientNumber--;
fflush(stdout);
} else if (readControl == -1) {
perror("recv failed");
}
//Free the socket pointer
free(socket_desc);
return 0;
}
int main(int argc, char *argv[]) {
int socket_desc, new_socket, c, *new_sock;
struct sockaddr_in server, client;
//Create Socket
socket_desc = socket(AF_INET, SOCK_STREAM, 0);
if (socket_desc == -1) {
puts("Could not create socket");
return 1;
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(8888);
if (bind(socket_desc, (struct sockaddr *) &server, sizeof(server)) < 0) {
puts("Binding failed");
return 1;
}
listen(socket_desc, 3);
puts("Server started");
c = sizeof(struct sockaddr_in);
while ((new_socket = accept(socket_desc, (struct sockaddr *) &client, (socklen_t *) &c)) &&
clientNumber < MAX_CLIENT_NUMBER) {
pthread_t sniffer_thread[MAX_CLIENT_NUMBER];
new_sock = malloc(1);
*new_sock = new_socket;
if (pthread_create(&sniffer_thread[clientNumber], NULL, connection_handler,
(void *) new_sock) < 0) {
perror("Could not create thread");
return 1;
} else {
clientNumber++;
}
puts("Client connected");
}
if (new_socket < 0) {
perror("accept failed");
return 1;
}
return 0;
}

Server closes connection before replying

I'm following the MSDN lessons about TCP/IP client; my issue is that the server isn't replying and the connection closes after I send the Headers.
const char *USR_PORT = "80";
#define BUFF_LEN 512
char recv_buf[BUFF_LEN];
const char HEADER_TO_SEND[] = "HEAD / HTTP/1.1\r\nHost: www.microsoft.com\r\nUser-Agent: RequestHeaderC\r\n\r\n";
{...}
do {
iRes = recv(ConnSocket, recv_buf, BUFF_LEN, 0);
if (iRes > 0)
{
printf("Bytes received: %d\n", iRes);
for (i = 0; (i < iRes) && recv_buf[i] != '\0'; i++)
printf("%c", recv_buf[i]);
}
else if (iRes == 0)
printf("Connection closed by the server.\n");
else printf("Error: %d\n", WSAGetLastError());
} while (iRes > 0);
I'm almost sure the connection was fine as I sent with success the bytes.
I don't receive any byte at all.
The other codes are almost the same as the ones in the tutorial, that's why I haven't posted them. If needed, I will
The server doesn't close the connection immediately if I remove this line:
shutdown(ConnSocket, SD_SEND);
But then I don't get any answer anyways, even if I add
Connection: close\r\n
in the headers
Full code:
const char *USR_PORT = "80";
#define BUFF_LEN 512
char USR_ADDR[] = "www.microsoft.com";
const char HEADER_TO_SEND[] = "HEAD / HTTP/1.1\r\nHost: www.microsoft.com\r\nUser-Agent: RequestHeaderC\r\nConnection: close\r\n\r\n";
int main()
{
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
printf("Error: Wsastartup\n");
exit(1);
}
int iRes;
addrinfo *result, *ptr, addr;
SecureZeroMemory(&addr, sizeof(addr));
addr.ai_family = AF_INET;
addr.ai_protocol = IPPROTO_TCP;
addr.ai_socktype = SOCK_STREAM;
iRes = getaddrinfo(USR_ADDR, USR_PORT, &addr, &result);
if ( iRes != 0 )
{
printf("Error: getaddrinfo");
WSACleanup();
exit(2);
}
SOCKET ConnSocket;
ptr = result;
ConnSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if (ConnSocket == INVALID_SOCKET)
{
printf("Error: socket: %ld \n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
exit(3);
}
if (connect(ConnSocket, ptr->ai_addr, (int)ptr->ai_addrlen) )
{
closesocket(ConnSocket);
ConnSocket = INVALID_SOCKET;
}
if (ConnSocket == INVALID_SOCKET)
{
printf("Invalid Socket\n");
exit(4);
}
const char *send_buf = HEADER_TO_SEND;
char recv_buf[BUFF_LEN];
if ((iRes = send(ConnSocket, send_buf, strlen(send_buf) - 1, 0)) == SOCKET_ERROR)
{
printf("Error: send\n");
closesocket(ConnSocket);
WSACleanup();
exit(5);
}
int i;
for (i = 0; i < iRes; i++)
printf("%c", send_buf[i]);
printf("Bytes sent: %d\n", iRes);
//if (shutdown(ConnSocket, SD_SEND) == SOCKET_ERROR)
//{
// printf("Error: shutdown: %d\n", WSAGetLastError());
// closesocket(ConnSocket);
// WSACleanup();
// exit(6);
//}
//do {
iRes = recv(ConnSocket, recv_buf, sizeof(recv_buf)-1, 0);
if (iRes > 0)
{
printf("Bytes received: %d\n", iRes);
recv_buf[iRes] = '\0';
for (i = 0; i < iRes; i++)
printf("%c", recv_buf[i]);
}
else if (iRes == 0)
printf("Connection closed by the server.\n");
else printf("Error: %d\n", WSAGetLastError());
//} while (iRes > 0);
getchar();
getchar();
closesocket(ConnSocket);
WSACleanup();
return 0;
}

Resources