Server closes connection before replying - c

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;
}

Related

Segfault in client disconnection

I have a simple client-server program implemented in C where a client can send integers to a server and the server replies with their sums. However, there is a troubling Segmentation fault (core dumped) shown on the server side whenever the client disconnects suddenly. The Client:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define PORT 5010
int main(int argc, char **argv) {
char buf[BUFSIZ], buf2[BUFSIZ], message[BUFSIZ], serverReply[BUFSIZ];
int SOCKET;
struct sockaddr_in server;
SOCKET = socket(AF_INET, SOCK_STREAM, 0);
if (SOCKET < 0) {
perror("Could not create socket");
return -1;
}
printf("Socket created\n");
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons(PORT);
if (connect(SOCKET, (struct sockaddr *) &server, sizeof(struct sockaddr_in)) < 0) {
perror("Could not connect");
return -1;
}
memset(&serverReply, 0, sizeof(serverReply));
printf("Connected to server.\nEnter first number: ");
scanf("%s", buf);
fflush(stdin);
printf("Enter second number: ");
scanf("%s", buf2);
strcat(buf, " ");
strcat(buf, buf2);
strcpy(message, buf);
if (send(SOCKET, message, strlen(message), 0) < 0) {
perror("Failed to send message");
return -1;
}
if (recv(SOCKET, serverReply, sizeof(serverReply), 0) < 0) {
perror("Could not receive message");
return -1;
}
printf("Server: %s", serverReply);
close(SOCKET);
}
The Server:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#define PORT 5010
int main(int argc, char *argv[]) {
char msg[BUFSIZ], reply[BUFSIZ];
struct sockaddr_in server, client;
int SOCKET, ACCEPT, READ, sockSize, num1, num2, option = 1, maxClients = 30,
h, clientSocket[maxClients], maxsd, sd, SELECT;
fd_set readfds;
for (h = 0; h < maxClients; h++) {
clientSocket[h] = 0;
}
SOCKET = socket(AF_INET, SOCK_STREAM, 0);
if (SOCKET == -1) {
perror("Could not create socket");
return -1;
}
if (setsockopt(SOCKET, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option)) == -1) {
perror("Could not set OPTNAME");
return -1;
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(PORT);
printf("Created socket.\n");
if (bind(SOCKET, (struct sockaddr *) &server, sizeof(server)) < 0) {
perror("Could not bind");
return -1;
}
if (listen(SOCKET, 1) < 0) {
perror("Listen failed");
return -1;
}
printf("Server is listening.\n");
sockSize = sizeof(struct sockaddr_in);
while (1) {
FD_ZERO(&readfds);
FD_SET(SOCKET, &readfds);
maxsd = SOCKET;
for (h = 0; h < maxClients; h++) {
sd = clientSocket[h];
if (sd > 0) { FD_SET(sd, &readfds); }
if (sd > maxsd) { maxsd = sd; }
}
SELECT = select(maxsd + 1, &readfds, NULL, NULL, NULL);
if ((SELECT < 0) && (errno != EINTR)) {
perror("select error");
}
if (FD_ISSET(SOCKET, &readfds)) {
ACCEPT = accept(SOCKET, (struct sockaddr *) &server, (socklen_t *) &sockSize);
if (ACCEPT < 0) {
perror("Could not accept client");
return -1;
}
for (h = 0; h < maxClients; h++) {
if (clientSocket[h] == 0) {
clientSocket[h] = ACCEPT;
break;
}
}
printf("Client has joined the server.\n");
}
for (h = 0; h < maxClients; h++) {
sd = clientSocket[h];
if (FD_ISSET(sd, &readfds)) {
READ = read(sd, msg, sizeof(msg));
if (READ == -1) {
perror("Could not receive message");
return -1;
}
if (READ == 0) {
printf("Client disconnected\n");
fflush(stdout);
clientSocket[h]=0;
}
int e = 0;
char *p = strtok(msg, " ");
char *arr[2];
while (p != NULL) {
arr[e++] = p;
p = strtok(NULL, " ");
}
num1 = atoi(arr[0]);
num2 = atoi(arr[1]);
if ((strcmp(arr[0], "0") != 0 && num1 != 0) && (strcmp(arr[1], "0") != 0 && num2 != 0)) {
printf("Client: %d, %d\n", num1, num2);
sprintf(reply, "%d\n", num1 + num2);
if (write(sd, reply, strlen(reply)) < 0) {
perror("Could not send message");
return -1;
}
memset(&reply, 0, sizeof(reply));
} else {
printf("Conversion error");
strcpy(reply, "Conversion error.");
if (write(sd, reply, strlen(reply)) < 0) {
perror("Could not send message");
return -1;
}
}
}
}
}
}
How can the segfault be solved? How else can the codes be improved?
The segfault comes from the atoi function since NULL is received. Checking for NULL seems to do the trick...

socket send fails with 10054 error when trying to connect to different port on a separate thread

I'm a newbie in tcp protocol and websocket.
I've estalished a connection between server and client and created another thread to send the packets received from the server to a websocket. And my code looks as below.
This is the server side of a code
int __cdecl main(int argc, char **argv)
{
WSADATA wsaData;
int iResult;
struct addrinfo *result = NULL,
*ptr = NULL,
hints;
char portStr[20];
SOCKET ConnectSocket = INVALID_SOCKET;
MSG_PACKET packet;
PQN_DATA_PACKET *ppacket;
PACKET_HEADER *ppacket_header;
queue<PQN_DATA_PACKET *> *pconnectionQ = new queue<PQN_DATA_PACKET *>();
char ps8bufsend[DEFAULT_BUFLEN];
char ps8bufrecv[DEFAULT_BUFLEN];
int packet_idx = 0;
PQN_DATA_PACKET* pstpacket;
int s8ack = 0;
std::string filename, path;
int s32packetlen = 0;
struct sockaddr_in serv_addr = {0};
struct sockaddr_in clnt_addr = {0};
const char* ip = LOCAL_IP;
SOCKET serv_sock = INVALID_SOCKET;
socklen_t clnt_addr_size;
int clnt_sock;
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0)
{
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
serv_sock = socket(PF_INET, SOCK_STREAM, 0);
if(serv_sock == -1)
{
printf( "socket() Error..Error --> Code %d ", WSAGetLastError() );
error_handling("socket error");
}
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = PF_INET;
serv_addr.sin_addr.s_addr = inet_addr(ip);
serv_addr.sin_port = htons(CLIENT_PORT_NUMBER);
if(bind(serv_sock, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) == -1)
{
printf( "bind() Error..Error --> Code %d ", WSAGetLastError() );
error_handling("bind error");
}
if(listen(serv_sock, 5) == -1)
{
printf( "listen() Error..Error --> Code %d ", WSAGetLastError() );
error_handling("listen error");
}
clnt_addr_size = sizeof(clnt_addr);
clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_addr, &clnt_addr_size);
if(clnt_sock == -1)
{
printf( "accept() Error..Error --> Code %d ", WSAGetLastError() );
error_handling("accept error");
}
FILE *fp = fopen( argv[1], "r+");
FILE *fpout = fopen("test.txt", "r");
ProcessFile(fp);
for(int i = 0; i < 5; i++)
{
if (i == ORDER_TIME_SETTING)
{
MSG_PDDAU_INFO_PACKET* ps8ptr = new MSG_PDDAU_INFO_PACKET;
s32packetlen = sizeof(MSG_PDDAU_INFO_PACKET);
if (clnt_sock == INVALID_SOCKET)
{
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
iResult = recv(clnt_sock, (char*)ps8ptr, s32packetlen, 0);
if (iResult == -1)
{
//fprintf(stderr, "recv Error Occurred %s (%d)\n", strerror(errno), errno);
printf("recv failed with error: %ld\n", WSAGetLastError());
return -1;
}
if (ps8ptr->header.msg_id != MSG_PDDAU_INFO_ID && ps8ptr->header.msg_type != MSG_REQUEST_TYPE)
{
printf("Time setting failed\n");
return -1;
}
if(!ps8ptr->time_enable)
{
printf("Time is disabled!\n");
return -1;
}
ps8ptr->header.msg_type = MSG_REQUEST_ACK_TYPE;
iResult = send(clnt_sock, (char*)ps8ptr, sizeof(MSG_PDDAU_INFO_PACKET), 0);
if (iResult == -1)
{
//fprintf(stderr, "send Error Occurred %s (%d)\n", strerror(errno), errno);
printf("send failed with error: %ld\n", WSAGetLastError());
return -1;
}
}
else if (i == ORDER_PDDAU_INFO)
{
MSG_PDDAU_INFO_PACKET* ps8ptr = new MSG_PDDAU_INFO_PACKET;
iResult = recv(clnt_sock, (char*)ps8ptr, sizeof(MSG_PDDAU_INFO_PACKET), 0);
if (iResult == -1)
{
//fprintf(stderr, "recv Error Occurred %s (%d)\n", strerror(errno), errno);
printf("recv failed with error: %ld\n", WSAGetLastError());
return -1;
}
if (ps8ptr->header.msg_id != MSG_PDDAU_INFO_ID && ps8ptr->header.msg_type != MSG_READ_INFO_TYPE)
{
printf("PDDAU Info Setting failed\n");
return -1;
}
ps8ptr->header.msg_type = MSG_READ_INFO_RESPONSE_TYPE;
iResult = send(clnt_sock, (char*)ps8ptr, sizeof(MSG_PDDAU_INFO_PACKET), 0);
if (iResult == -1)
{
//fprintf(stderr, "send Error Occurred %s (%d)\n", strerror(errno), errno);
printf("send failed with error: %ld\n", WSAGetLastError());
return -1;
}
}
else if (i == ORDER_RF_INFO)
{
MSG_RF_INFO_PACKET* ps8ptr = new MSG_RF_INFO_PACKET;
iResult = recv(clnt_sock, (char*)ps8ptr, sizeof(MSG_RF_INFO_PACKET), 0);
if (iResult == -1)
{
//fprintf(stderr, "recv Error Occurred %s (%d)\n", strerror(errno), errno);
printf("recv failed with error: %ld\n", WSAGetLastError());
return -1;
}
if (ps8ptr->header.msg_id != MSG_RF_INFO_ID && ps8ptr->header.msg_type != MSG_READ_INFO_TYPE)
{
printf("PDDAU Info Setting failed\n");
return -1;
}
ps8ptr->header.msg_type = MSG_READ_INFO_RESPONSE_TYPE;
iResult = send(clnt_sock, (char*)ps8ptr, sizeof(MSG_RF_INFO_PACKET), 0);
if (iResult == -1)
{
//fprintf(stderr, "send Error Occurred %s (%d)\n", strerror(errno), errno);
printf("send failed with error: %ld\n", WSAGetLastError());
return -1;
}
}
else if(i == ORDER_PD_DATA)
{
printf("Yo 1\n");
MSG_PD_PACKET* ps8ptr = new MSG_PD_PACKET;
iResult = recv(clnt_sock, (char*)ps8ptr, sizeof(MSG_PD_PACKET), 0);
if (iResult == -1)
{
//fprintf(stderr, "recv Error Occurred %s (%d)\n", strerror(errno), errno);
printf("recv failed with error: %ld\n", WSAGetLastError());
return -1;
}
if (ps8ptr->header.msg_id != MSG_PD_START_ID && ps8ptr->header.msg_type != MSG_REQUEST_TYPE)
{
printf("PDDAU Info Setting failed\n");
return -1;
}
ps8ptr->header.msg_type = MSG_REQUEST_ACK_TYPE;
iResult = send(clnt_sock, (char*)ps8ptr, sizeof(MSG_PD_PACKET), 0);
if (iResult == -1)
{
//fprintf(stderr, "send Error Occurred %s (%d)\n", strerror(errno), errno);
printf("send failed with error: %ld\n", WSAGetLastError());
return -1;
}
}
else
{
MSG_PD_PACKET* ps8ptr = new MSG_PD_PACKET;
printf("Yo 2\n");
iResult = recv(clnt_sock, (char*)ps8ptr, sizeof(MSG_PD_PACKET), 0);
if (iResult == -1)
{
fprintf(stderr, "recv Error Occurred %s (%d)\n", strerror(errno), errno);
return -1;
}
if(ps8ptr->header.msg_type != MSG_REQUEST_TYPE || ps8ptr->header.msg_id != MSG_PD_START_ID)
{
printf("PD Sending failed\n");
return -1;
}
ps8ptr->header.msg_type = MSG_REQUEST_ACK_TYPE;
iResult = send(clnt_sock, (char*) ps8ptr, sizeof(MSG_PD_PACKET), 0);
if (iResult == -1)
{
printf("Yo 2\n");
fprintf(stderr, "send Error Occurred %s (%d)\n", strerror(errno), errno);
return -1;
}
while(fgets(ps8bufsend, ONE_CYCLE, fpout) != NULL)
{
memset(ps8ptr->data,0,ONE_CYCLE);
memcpy(ps8ptr->data, ps8bufsend, ONE_CYCLE);
boost::asio::io_context io;
boost::asio::steady_timer t(io, boost::asio::chrono::milliseconds(83));
packet_idx++;
ps8ptr->header.msg_id = MSG_PD_SEND_ID;
ps8ptr->header.msg_type = MSG_SEND_TYPE;
printf("Yo 3\n");
s8ack = send(clnt_sock,(char*)ps8ptr, sizeof(MSG_PD_PACKET),0);
printf("Yo 4\n");
if (s8ack == -1)
{
printf("Yo 5\n");
//fprintf(stderr, "send Error Occurred %s (%d)\n", strerror(errno), errno);
printf("send failed with error: %ld\n", WSAGetLastError());
return -1;
}
This is my client side of the code.
int __cdecl main(int argc, char **argv)
{
PQN_DATA_PACKET* pstpacket;
//int serv_sock;
SOCKET serv_sock = INVALID_SOCKET;
int clnt_sock;
WSADATA wsaData;
int nErrorStatus;
WORD wVersionRequested = MAKEWORD(2, 2);
const char* ip = LOCAL_IP;
struct sockaddr_in serv_addr = {0};
struct sockaddr_in clnt_addr = {0};
struct addrinfo *result = NULL,
*ptr = NULL,
hints;
socklen_t clnt_addr_size;
char buff[255];
int iResult;
queue<PQN_DATA_PACKET *> *pconnectionQ = new queue<PQN_DATA_PACKET *>();
DWORD RunWebServerThreadID;
nErrorStatus = WSAStartup(wVersionRequested, &wsaData);
PACKET_HEADER *ppacket_header;
ppacket_header = new PACKET_HEADER;
std::fstream datfile;
std::string filename, path;
SOCKET ConnectSocket = INVALID_SOCKET;
char ps8bufsend[DEFAULT_BUFLEN];
char ps8bufrecv[DEFAULT_BUFLEN];
int order[] = {ORDER_TIME_SETTING, ORDER_PDDAU_INFO, ORDER_RF_INFO, ORDER_PD_DATA};
int s32packetlen = 0;
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
iResult = getaddrinfo(LOCAL_IP, "8081", &hints, &result);
if (iResult != 0)
{
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
// Attempt to connect to an address until one succeeds
for (ptr = result; ptr != NULL; ptr = ptr->ai_next)
{
// Create a SOCKET for connecting to server
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype,
ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET)
{
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
// Connect to server.
iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR)
{
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
continue;
}
break;
}
if (ConnectSocket == INVALID_SOCKET)
{
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
HANDLE t2 = CreateThread(0, 0, RunWebServerThread, pconnectionQ, 0, &RunWebServerThreadID);
for (int i = 0; i < 5; i++)
{
//while(1)
//{
if(i == ORDER_TIME_SETTING)
{
MSG_PDDAU_INFO_PACKET* ps8ptr = new MSG_PDDAU_INFO_PACKET;
ps8ptr->header.msg_id = MSG_PDDAU_INFO_ID;
ps8ptr->header.msg_type = MSG_REQUEST_TYPE;
ps8ptr->time_enable = 0x01;
s32packetlen = sizeof(MSG_PDDAU_INFO_PACKET);
printf("ConnectSocket=%i\n", ConnectSocket);
iResult = send(ConnectSocket, (char*)ps8ptr, s32packetlen, 0);
if (iResult == -1)
{
fprintf(stderr, "send Error Occurred %s (%d)\n", strerror(errno), errno);
return -1;
}
memset(ps8ptr, 0, s32packetlen);
iResult = recv(ConnectSocket, (char*)ps8ptr, s32packetlen, 0);
if (iResult == -1)
{
fprintf(stderr, "recv Error Occurred %s (%d)\n", strerror(errno), errno);
return -1;
}
printf("recv result : %d\n",iResult);
printf("header msg_id : %d\n", ps8ptr->header.msg_id);
if (ps8ptr->header.msg_type != MSG_REQUEST_ACK_TYPE)
{
printf("Time setting failed\n");
return -1;
}
delete ps8ptr;
ps8ptr = NULL;
}
else if(i == ORDER_PDDAU_INFO)
{
MSG_PDDAU_INFO_PACKET* ps8ptr = new MSG_PDDAU_INFO_PACKET;
ps8ptr->header.msg_id = MSG_PDDAU_INFO_ID;
ps8ptr->header.msg_type = MSG_READ_INFO_TYPE;
iResult = send(ConnectSocket, (char*)ps8ptr, sizeof(MSG_PDDAU_INFO_PACKET), 0);
if (iResult == -1)
{
fprintf(stderr, "send Error Occurred %s (%d)\n", strerror(errno), errno);
return -1;
}
memset(ps8ptr, 0, sizeof(MSG_PDDAU_INFO_PACKET));
iResult = recv(ConnectSocket, (char*)ps8ptr, sizeof(MSG_PDDAU_INFO_PACKET), 0);
if (iResult == -1)
{
fprintf(stderr, "recv Error Occurred %s (%d)\n", strerror(errno), errno);
return -1;
}
if (ps8ptr->header.msg_type != MSG_READ_INFO_RESPONSE_TYPE)
{
printf("PDDAU Info Setting failed\n");
return -1;
}
delete ps8ptr;
ps8ptr = NULL;
}
else if(i == ORDER_RF_INFO)
{
MSG_RF_INFO_PACKET* ps8ptr = new MSG_RF_INFO_PACKET;
ps8ptr->header.msg_id = MSG_RF_INFO_ID;
ps8ptr->header.msg_type = MSG_READ_INFO_TYPE;
iResult = send(ConnectSocket, (char*) ps8ptr, sizeof(MSG_RF_INFO_PACKET), 0);
if (iResult == -1)
{
fprintf(stderr, "send Error Occurred %s (%d)\n", strerror(errno), errno);
return -1;
}
memset(ps8ptr, 0, sizeof(MSG_RF_INFO_PACKET));
iResult = recv(ConnectSocket, (char*)ps8ptr, sizeof(MSG_RF_INFO_PACKET), 0);
if (iResult == -1)
{
fprintf(stderr, "recv Error Occurred %s (%d)\n", strerror(errno), errno);
return -1;
}
if (ps8ptr->header.msg_type != MSG_READ_INFO_RESPONSE_TYPE)
{
printf("RF Info Setting failed\n");
return -1;
}
delete ps8ptr;
}
else if(i == ORDER_PD_DATA)
{
MSG_PD_PACKET* ps8ptr = new MSG_PD_PACKET;
ps8ptr->header.msg_id = MSG_PD_START_ID;
ps8ptr->header.msg_type = MSG_REQUEST_TYPE;
iResult = send(ConnectSocket, (char*) ps8ptr, sizeof(MSG_PD_PACKET), 0);
if (iResult == -1)
{
fprintf(stderr, "send Error Occurred %s (%d)\n", strerror(errno), errno);
return -1;
}
memset(ps8ptr, 0, sizeof(MSG_PD_PACKET));
iResult = recv(ConnectSocket, (char*)ps8ptr, sizeof(MSG_PD_PACKET), 0);
if (iResult == -1)
{
fprintf(stderr, "recv Error Occurred %s (%d)\n", strerror(errno), errno);
return -1;
}
if (ps8ptr->header.msg_type != MSG_REQUEST_ACK_TYPE)
{
printf("RF Info Setting failed\n");
return -1;
}
delete ps8ptr;
}
else
{
MSG_PD_PACKET *ps8ptr = new MSG_PD_PACKET;
ps8ptr->header.msg_id = MSG_PD_START_ID;
ps8ptr->header.msg_type = MSG_REQUEST_TYPE;
ps8ptr->header.body_len = sizeof(MSG_PD_PACKET);
ps8ptr->ch_idx = 1;
printf("Error?\n");
iResult = send(ConnectSocket, (char*) ps8ptr, sizeof(MSG_PD_PACKET), 0);
if (iResult == -1)
{
fprintf(stderr, "send Error Occurred %s (%d)\n", strerror(errno), errno);
return -1;
}
memset(ps8ptr, 0, sizeof(MSG_PD_PACKET));
iResult = recv(ConnectSocket, (char*)ps8ptr, sizeof(MSG_PD_PACKET), 0);
if (iResult == -1)
{
fprintf(stderr, "recv Error Occurred %s (%d)\n", strerror(errno), errno);
return -1;
}
if (ps8ptr->header.msg_type != MSG_REQUEST_ACK_TYPE)
{
printf("RF Info Setting failed\n");
return -1;
}
while(1)
{
MSG_PD_PACKET *ps8data = new MSG_PD_PACKET;
printf("Error 2?\n");
iResult = recv(ConnectSocket, (char*)ps8ptr, sizeof(MSG_PD_PACKET), 0);
if (iResult == -1)
{
fprintf(stderr, "recv Error Occurred %s (%d)\n", strerror(errno), errno);
return -1;
}
if(ps8ptr->header.msg_type != MSG_SEND_TYPE || ps8ptr->header.msg_id != MSG_PD_SEND_ID)
{
printf("PD Sending failed. type : %x, id : %x\n", ps8ptr->header.msg_type, ps8ptr->header.msg_id);
return -1;
}
std::lock_guard<std::mutex> lock_guard(queue_mutex2);
(*pconnectionQ).push(pstpacket);
And here is the thread function I run on the client side.
DWORD WINAPI RunWebServerThread(LPVOID lpParameter)
{
//server srv;
//srv.run(tcp::endpoint(tcp::v6(), SERVER_PORT_NUMBER), 1);
int threads(1);
net::io_context ioc{ threads };
queue<PQN_DATA_PACKET *> *pconnectionQ = (queue<PQN_DATA_PACKET *> *)lpParameter;
auto const address = net::ip::make_address(LOCAL_IP);
// Create and launch a listening port
std::make_shared<listener>(ioc, tcp::endpoint{ address, SERVER_PORT_NUMBER }, pconnectionQ)->run();
// Run the I/O service on the requested number of threads
std::vector<std::thread> v;
v.reserve(threads - 1);
for (auto i = threads - 1; i > 0; --i)
v.emplace_back(
[&ioc]
{
ioc.run();
});
ioc.run();
}
As you can see there is no correlation between the port used in the thread function and main socket.
However, here is the output I've got on the server side once I connect frontend websocket.
Yo 3
Yo 4
Yo 3
Yo 4
Yo 5
send failed with error: 10054
Can anyone point out the possible problem with this code?
Thank you in advance.
Okay. I've solved the problem myself.
The reason the connection was closed is because I've been using the wrong type of data packet. It was supposed to be something else other than PQN_DATA_PACKET.
Thus, the thread function died and affected the regular connection since it couldn't handle the right type of the packet.
It was an amateur mistake in my part..
Thanks everyone for focusing on my problem.

make a https get request in linux based on openssl

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;
}

C Socket program doesn't print desired output (No Error)

I can't seem to print what I enter in my client. I have compiled both without any error. Can't figure out why it isn't printing the desired output.
Q. What is wrong with my code ? How can I print a string with whitespaces through the client in the server.
Here is the code for the server.
/* Server Side program */
int sid,nid;
struct sockaddr_in q;
char x[100];
int len=sizeof(struct sockaddr_in);
sid=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
q.sin_family=PF_INET;
q.sin_port=1600;
q.sin_addr.s_addr=0;
bind(sid,&q,len);
listen(sid,20);
while(1)
{
memset(x,0,sizeof(x));
nid=accept(sid,&q,&len);
read(nid,x,100);
printf("%s\n",x);
}
Here is the code for the client.
/*client side program*/
int sid,status;
struct sockaddr_in q;
int len=sizeof(struct sockaddr_in);
char x[100];
sid=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
q.sin_family=PF_INET;
q.sin_port=1600;
q.sin_addr.s_addr=0;
status=connect(sid,&q,len);
if(status==-1)
{
printf("Connection failure");
exit(0);
}
while(1)
{
printf("Enter string to send : ");
scanf("%[^\n]s",x);
write(sid,x,strlen(x));
if(strcmp(x,"bye")==0)
break;
}
There is all kinds of problems with your code. Lack of error handling. Incorrect use of printf() and scanf(). Resource leaks.
Try something more like this instead:
Server:
int main()
{
int sid, nid;
struct sockaddr_in q;
char x[100];
socklen_t qlen;
ssize_t xlen;
sid = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sid < 0)
{
perror("socket failure");
return -1;
}
q.sin_family = AF_INET;
q.sin_port = htons(1600);
q.sin_addr.s_addr = INADDR_ANY;
if (bind(sid, &q, sizeof(q)) < 0)
{
perror("bind failure");
return -1;
}
if (listen(sid, 20) < 0)
{
perror("listen failure");
return -1;
}
while(1)
{
qlen = sizeof(q);
nid = accept(sid, &q, &qlen);
if (nid < 0)
{
perror("accept failure");
return -1;
}
while ((xlen = read(nid, x, sizeof(x))) > 0)
{
printf("Received: '%.*s'\n", xlen, x);
}
if (xlen < 0)
perror("read failure");
else
printf("client disconnected\n");
close(nid);
}
return 0;
}
Client:
int main()
{
int sid, xlen;
struct sockaddr_in q;
char x[100];
sid = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sid < 0)
{
perror("socket failure");
return -1;
}
q.sin_family = AF_INET;
q.sin_port = htons(1600);
q.sin_addr.s_addr = inet_addr("server ip here"); // or INADDR_LOOPBACK (127.0.0.1)
if (connect(sid, &q, sizeof(q)) < 0)
{
printf("connect failure");
return -1;
}
while(1)
{
printf("Enter string to send : ");
if (!fgets(x, sizeof(x), stdin))
break;
xlen = strlen(x);
if ((xlen > 0) && (x[xlen-1] == '\n'))
{
x[xlen-1] = '\0';
--xlen;
}
if (write(sid, x, xlen) < 0)
{
perror("write failure");
break;
}
if (strcmp(x, "bye") == 0)
break;
}
close(sid);
return 0;
}

Client-server echo-chat (multiplexing I/O + threads)

I just started learning C language and I'm trying to get deal with Windows Sockets.
The problem is the server can accept and send message only once.
I used debug mode and saw that work stops in select() from the server part. It seems fine in client (but I'm not sure) and don't see the problem in my code. But I have such a result. What's wrong?
I noticed that my tv.tv_sec isn't defined and I did that just before select, nothing was changed.
And just to be sure: as I need to receive and send message, I don't need write descriptor in accept(), right?
Client uses CreateThread function where I try to send message. Send is in while(1) cycle in main()
Server part:
int main(int argc, char* argv[])
{
/* definitions, WSAStartup(), socket(), bind(), listen()
Listening socket is a returned value of listen() function*/
FD_ZERO(&readSet);
FD_ZERO(&writeSet);
while (1)
{
// SELECT (LISTENING SOCKET)
FD_ZERO(&readSet);
FD_SET(listeningSocket, &readSet);
tv.tv_sec = 5;
printf("Listening: Read FD: %d; Write FD : %d;\n", FD_ISSET(listeningSocket, &readSet), FD_ISSET(listeningSocket, &writeSet));
if ((retVal = select(listeningSocket + 1, &readSet, NULL, NULL, 0)) == SOCKET_ERROR)
{
printf("Select error ");
break;
}
else if (retVal == 0)
{
printf(". . .\n");
continue;
}
else
{
// READ SD
if ((FD_ISSET(listeningSocket, &readSet)) != SOCKET_ERROR)
{
if ((newSocketDescriptor = accept(listeningSocket, (struct sockaddr *)&clientAddr, &clientAddrSize)) == SOCKET_ERROR)
{
printf("Accept error ");
break;
}
FD_ZERO(&readSet);
FD_SET(newSocketDescriptor, &readSet);
HOSTENT *hst = gethostbyaddr((const char *)&serverAddr.sin_addr.s_addr, 4, AF_INET);
printf("Welcome %s (%s:%d) new connected\n", hst->h_name, inet_ntoa(clientAddr.sin_addr), ntohs(clientAddr.sin_port));
printf("Read FD: %d; Write FD : %d;\n", FD_ISSET(newSocketDescriptor, &readSet), FD_ISSET(newSocketDescriptor, &writeSet));
// READ
if (FD_ISSET(newSocketDescriptor, &readSet) != 0)
{
if ((numBytes = recv(newSocketDescriptor, &bufferData[0], sizeof(bufferData), 0)) == SOCKET_ERROR)
{
printf("Recv failed \n");
freeSocketInformation(newSocketDescriptor);
break;
}
bufferData[numBytes] = '\0';
printf("Client -> Server: %s\n", &bufferData[0]);
}
// WRITE
FD_ZERO(&writeSet);
FD_SET(newSocketDescriptor, &writeSet);
printf("Read FD: %d; Write FD : %d;\n", FD_ISSET(newSocketDescriptor, &readSet), FD_ISSET(newSocketDescriptor, &writeSet));
if (FD_ISSET(newSocketDescriptor, &writeSet) != 0)
{
//fgets(&bufferData[0], sizeof(bufferData), stdin);
if (send(newSocketDescriptor, &bufferData[0], strlen(&bufferData[0]), 0) == SOCKET_ERROR)
{
printf("Send error ");
freeSocketInformation(newSocketDescriptor);
break;
}
bufferData[numBytes] = '\0';
printf("Server -> Client: %s\n", &bufferData[0]);
}
printf("Read FD: %d; Write FD : %d;\n", FD_ISSET(newSocketDescriptor, &readSet), FD_ISSET(newSocketDescriptor, &writeSet));
FD_SET(newSocketDescriptor, &readSet);
}
}
}
//FD_CLR(listeningSocket, &readSet);
closesocket(newSocketDescriptor);
} while (FALSE);
printf("- Error code: %d\n", WSAGetLastError());
closesocket(listeningSocket);
WSACleanup();
return 0;
}
Client part (it uses CreateThread function which is in the end of the code):
/* definitions, socket(), connect()*/
if (ioctlsocket(socketDescriptor, FIONBIO, (unsigned long *)&nb) != 0)
{
printf("ioctlsocket error ");
break;
}
FD_ZERO(&writeSet);
FD_SET(socketDescriptor, &writeSet);
if ((retVal = select(socketDescriptor + 1, NULL, &writeSet, NULL, &tv)) == SOCKET_ERROR)
{
printf("Send non-blocking error ");
break;
}
else if (retVal == 0)
{
printf("Non-blocking connect time limit is expired");
break;
}
}
printf("Connection with %s\n", SERVERADDR);
DWORD thID;
printf("Socket Desciptor: %d\n", socketDescriptor);
HANDLE hThread = CreateThread(NULL, NULL, HandleReadThread, (LPVOID)socketDescriptor, NULL, &thID);
printf("Thread ID: %d\n", thID);
while (1)
{
// WRITE
printf("Client -> Server: ");
fgets(&bufferData[0], sizeof(bufferData), stdin);
FD_ZERO(&writeSet);
FD_SET(socketDescriptor, &writeSet);
tv.tv_sec = 5;
if ((retVal = select(socketDescriptor + 1, NULL, &writeSet, NULL, &tv)) == SOCKET_ERROR)
{
printf("Send non-blocking error ");
break;
}
if (FD_ISSET(socketDescriptor, &writeSet) != 0)
{
if (send(socketDescriptor, bufferData, strlen(&bufferData[0]), 0) == SOCKET_ERROR)
{
printf("Send error ");
break;
}
}
}
} while (FALSE);
printf("- Error code: %d\n", WSAGetLastError());
closesocket(socketDescriptor);
WSACleanup();
return 0;
}
DWORD WINAPI HandleReadThread(LPVOID serverSocket)
{
SOCKET socketDescriptor;
socketDescriptor = (SOCKET)serverSocket;
char bufferData[MAXDATASIZE] = { 0 };
int retVal;
fd_set readSet;
timeval tv = { 0 };
tv.tv_sec = 5;
int numBytes;
int nclients = 0;
while (1)
{
FD_ZERO(&readSet);
FD_SET(socketDescriptor, &readSet);
if ((retVal = select(socketDescriptor + 1, &readSet, NULL, NULL, &tv)) == SOCKET_ERROR)
{
printf("Select error. Error code: %d", WSAGetLastError());
break;
}
else if (retVal == 0)
{
//printf(". . .\n");
continue;
}
else
{
//FD_ZERO(socketDescriptor, &readSet);
//FD_SET(socketDescriptor, &readSet);
// READ
if (FD_ISSET(socketDescriptor, &readSet) != 0)
{
if ((numBytes = recv(socketDescriptor, &bufferData[0], sizeof(bufferData), 0)) == SOCKET_ERROR)
{
printf("Recv error in Thread. Error code: %d\n", WSAGetLastError());
break;
}
printf("\nSocket Desciptor: %d\n", socketDescriptor);
bufferData[numBytes] = '\0';
printf("Server -> Client: %s\n", &bufferData[0]);
}
}
}
closesocket(socketDescriptor);
return 0;
}
Well, I solved it by myself. The condition
if ((FD_ISSET(listeningSocket, &readSet)) != 0)
worked for all while(1) cycle, it should has been finished after accept() function.
Also I added these lines in the beginning of while(1) after FD_SET for readSet:
if (newSocketDescriptor)
{
FD_SET(newSocketDescriptor, &readSet);
}
The chat started working but there are a lot of stuffs to work at :)

Resources