Reputation: 139
I'm korean student. I'm writing web server program by written C. I'don't know why client(javascript) cannot receive data from server. client(browser) is also well connect to server. but client cannot receive data from server.
I have searched about my problem on google. but I could not find out the reason. the search output was all just relavant usage of library. please see my code if you have a time to see
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <process.h>
#include <sys/types.h>
#include <windows.h>
#include "dirent.h"
#define BUF_SIZE 2048
#define BUF_SMALL 100
unsigned WINAPI RequestHandler(void* arg);
char* ContentType(char* file);
void SendData(SOCKET sock, char* ct, char* fileName);
void SendErrorMSG(SOCKET sock);
void ErrorHandling(char *message);
unsigned WINAPI updateFiles(void* arg);
typedef struct _clnt {
SOCKET hClntSock;
SOCKADDR_IN* clntAdr;
}Clnt, *LPClnt;
enum FLAG { SEND_TO_WEB, SEND_TO_CLIENT };
SOCKET hServSock;
SOCKADDR_IN servAdr;
int flag;
int main(int argc, char *argv[])
{
WSADATA wsaData;
SOCKET hClntSock;
SOCKADDR_IN* clntAdr;
LPClnt clnt;
HANDLE hThread;
DWORD dwThreadID;
int clntAdrSize;
if (argc != 2) {
printf("Usage : %s <port>\n", argv[0]);
exit(1);
}
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
ErrorHandling("WSAStartup() error!");
hServSock = socket(PF_INET, SOCK_STREAM, 0);
memset(&servAdr, 0, sizeof(servAdr));
servAdr.sin_family = AF_INET;
servAdr.sin_addr.s_addr = htonl(INADDR_ANY);
servAdr.sin_port = htons(atoi(argv[1]));
if (bind(hServSock, (SOCKADDR*)&servAdr, sizeof(servAdr)) == SOCKET_ERROR)
ErrorHandling("bind() error");
if (listen(hServSock, 5) == SOCKET_ERROR)
ErrorHandling("listen() error");
/* 요청 및 응답 */
while (1)
{
clnt = (LPClnt)malloc(sizeof(Clnt));
clntAdr = (SOCKADDR_IN*)malloc(sizeof(SOCKADDR_IN));
clntAdrSize = sizeof(*clntAdr);
hClntSock = accept(hServSock, (SOCKADDR*)clntAdr, &clntAdrSize);
clnt->clntAdr = clntAdr;
clnt->hClntSock = hClntSock;
printf("Connection Request : %s:%d\n",
inet_ntoa(clntAdr->sin_addr), ntohs(clntAdr->sin_port));
printf("Socket Number : %d\n", clnt->hClntSock);
hThread = (HANDLE)_beginthreadex(
NULL, 0, RequestHandler, (void*)clnt, 0, (unsigned *)&dwThreadID);
}
closesocket(hServSock);
WSACleanup();
return 0;
}
unsigned WINAPI RequestHandler(void *arg)
{
SOCKET hClntSock = ((LPClnt)arg)->hClntSock;
SOCKADDR_IN* clntAdr = ((LPClnt)arg)->clntAdr;
char buf[BUF_SIZE];
char method[BUF_SMALL];
char ct[BUF_SMALL];
char fileName[BUF_SMALL];
char* context;
recv(hClntSock, buf, BUF_SIZE, 0);
if (strstr(buf, "HTTP/") == NULL) // HTTP에 의한 요청인지 확인
{
SendErrorMSG(hClntSock);
closesocket(hClntSock);
return 1;
}
else if (strstr(buf, "websocket")) {
printf("WebSocket is connected\n");
_beginthreadex(NULL, 0, updateFiles, (void*)hClntSock, 0, NULL);
return 1;
}
strcpy_s(method, sizeof(method), strtok_s(buf, " /", &context));
if (strcmp(method, "GET")) // GET 방식 요청인지 확인
SendErrorMSG(hClntSock);
strcpy_s(fileName, sizeof(fileName), strtok_s(NULL, " /", &context)); // 요청 파일이름 확인
if(!strcmp(fileName, "HTTP")) // index.html을 명시하지않앗다면
strcpy_s(fileName, sizeof(fileName), "index.html");
strcpy_s(ct, sizeof(ct), ContentType(fileName)); // Content-type 확인
SendData(hClntSock, ct, fileName); // 응 답
return 0;
}
void SendData(SOCKET sock, char* ct, char* fileName)
{
char protocol[] = "HTTP/1.0 200 OK\r\n";
char servName[] = "Server:simple web server\r\n";
char cntLen[] = "Content-length:2048\r\n";
char cntType[BUF_SMALL];
char buf[BUF_SIZE];
FILE* sendFile;
sprintf_s(cntType, sizeof(cntType), "Content-type:%s; charset=UTF-8\r\n\r\n", ct);
if (fopen_s(&sendFile, fileName, "r") != 0)
{
SendErrorMSG(sock);
return;
}
/* 헤더 정보 전송 */
send(sock, protocol, strlen(protocol), 0);
send(sock, servName, strlen(servName), 0);
send(sock, cntLen, strlen(cntLen), 0);
send(sock, cntType, strlen(cntType), 0);
/* 요청 데이터 전송 */
while (fgets(buf, BUF_SIZE, sendFile) != NULL) {
send(sock, buf, strlen(buf), 0);
}
closesocket(sock); // HTTP 프로토콜에 의해서 응답 후 종료
}
void SendErrorMSG(SOCKET sock) // 오류 발생시 메시지 전달
{
char protocol[] = "HTTP/1.0 400 Bad Request\r\n";
char servName[] = "Server:simple web server\r\n";
char cntLen[] = "Content-length:2048\r\n";
char cntType[] = "Content-type:text/html\r\n\r\n";
char content[] = "<html><head><title>NETWORK</title></head>"
"<body><p>오류 발생! 요청 파일명 및 요청 방식 확인!"
"</p></body></html>";
send(sock, protocol, strlen(protocol), 0);
send(sock, servName, strlen(servName), 0);
send(sock, cntLen, strlen(cntLen), 0);
send(sock, cntType, strlen(cntType), 0);
send(sock, content, strlen(content), 0);
closesocket(sock);
}
char* ContentType(char* file) // Content-Type 구분
{
char extension[BUF_SMALL];
char fileName[BUF_SMALL];
char* context;
strcpy_s(fileName, sizeof(fileName), file);
strtok_s(fileName, ".", &context);
strcpy_s(extension, sizeof(extension), strtok_s(NULL, ".", &context));
if (!strcmp(extension, "html") || !strcmp(extension, "htm"))
return "text/html";
else
return "text/plain";
}
unsigned WINAPI updateFiles(void* arg) {
struct dirent* file;
char* str;
SOCKET webSock = (SOCKET)arg;
DIR* dir;
while (1) {
dir = opendir(".");
printf("to sent %d\n", webSock);
while (file = readdir(dir)) {
//printf("%s\n", file->d_name);
send(webSock, 1, 1, 0);
}
Sleep(1000);
}
}
void ErrorHandling(char* message)
{
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
<html>
<head>
<meta charset="UTF-8">
<title>NETWORK</title>
</head>
<body>
<ul id="list">
<li>
first11
</li>
<li>
second
</li>
</ul>
</body>
<script>
const list = document.querySelector("#list");
const sock = new WebSocket('ws://127.0.0.1:80');
const arr = [];
let li;
sock.onmessage = evt => {
console.log("ASD")
li = document.createElement("li");
if (arr.indexOf(evt.data) == -1) {
arr.push(evt.data);
li.innerHTML = evt.data;
list.appendChild(li);
}
}
</script>
</html>
this is my output. if my program don't has problem, browser has to output "ASD", but there is nothing.
Upvotes: 0
Views: 4619
Reputation: 19221
WebSockets is the name of a protocol, it's not raw TCP/IP sockets.
Make sure you wrap the TCP/IP data in a WebSocket packet before sending the data to the TCP/IP connection.
Also, don't write HTTP data to the WebSocket after the HTTP protocol was "upgraded".
See the RFC for the WebSocket protocol for details.
Upvotes: 1