最近在学习写socket程序,然后就写了一个模拟web服务器的应答程序,下面我上源码。
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <assert.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#define BUFFER_SIZE 1024
static const char *status_line[2] = {"200 OK", "500 Internal server error"};
int main(int argc, char *argv[]){
if(argc <= 3){
printf("usage: %s ip_address port_number filename\n", basename(argv[0]));
return 1;
}
const char* ip = argv[1];
int port = atoi(argv[2]);
const char *file_name = argv[3];
struct sockaddr_in address;
bzero(&address, sizeof(address));
address.sin_family = AF_INET;
inet_pton(AF_INET, ip, &address.sin_addr);
address.sin_port = htons(port);
int sock = socket(PF_INET, SOCK_STREAM, 0);
assert(sock >= 0);
int ret = bind(sock, (struct sockaddr*)&address, sizeof(address));
assert(ret != -1);
struct sockaddr_in client;
socklen_t client_addrlength = sizeof(client);
int connfd = accept(sock, (struct sockaddr*)&client, &client_addrlength);
if(connfd < 0){
printf("errno is : %d\n", errno);
}else{
char header_buf[BUFFER_SIZE];
memset(header_buf, '\0', BUFFER_SIZE);
char *file_buf;
struct stat file_stat;
bool valid = true;
int len = 0;
if(stat(file_name, &file_stat) < 0){
valid = false;
}else{
if(S_ISDIR(file_stat.st_mode)){
valid = false;
}else if(file_stat.st_mode & S_IROTH){
int fd = open(file_name, O_RDONLY);
file_buf = new char[file_stat.st_size + 1];
memset(file_buf, '\0', file_stat.st_size + 1);
if(read(fd, file_buf, file_stat.st_size) < 0){
valid = false;
}
}else{
valid = false;
}
}
if(valid){
ret = snprintf(header_buf, BUFFER_SIZE-1, "%s %s\r\n", "HTTP/1.1",
status_line[0]);
len += ret;
ret = snprintf(header_buf + len, BUFFER_SIZE-1-len,
"Content-Length: %d\r\n", file_stat.st_size);
len += ret;
ret = snprintf(header_buf + len, BUFFER_SIZE-1-len, "%s", "\r\n");
struct iovec iv[2];
iv[0].iov_base = header_buf;
iv[0].iov_len = strlen(header_buf);
iv[1].iov_base = file_buf;
iv[1].iov_len = file_stat.st_size;
ret = writev(connfd, iv, 2);
}else{
ret = snprintf(header_buf, BUFFER_SIZE-1, "%s %s\r\n",
"HTTP/1.1", status_line[1]);
len += ret;
ret = snprintf(header_buf + len, BUFFER_SIZE-1-len, "%s", "\r\n");
send(connfd, header_buf, strlen(header_buf), 0);
}
close(connfd);
delete[] file_buf;
}
close(sock);
return 0;
}我编译运行之后,总是报errno 22的错误。
./writev 192.168.91.128 5555 count1.cerrno is : 22因为这个实在accept的函数中打印出来了,我查了一下errno,说是参数错误,然后我就去翻accept的定义啊,看了很久,觉得没什么问题啊。
然后上 优快云,也看到一个小伙伴报同样的错误,我就看了下他贴上来的源码,突然看到了listen,恍然大悟啊,我竟然在bind之后没有listen~~~~~~
可恶啊!!!
后来加上listen之后就没有问题了。
完整的源码:
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <assert.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#define BUFFER_SIZE 1024
static const char *status_line[2] = {"200 OK", "500 Internal server error"};
int main(int argc, char *argv[]){
if(argc <= 3){
printf("usage: %s ip_address port_number filename\n", basename(argv[0]));
return 1;
}
const char* ip = argv[1];
int port = atoi(argv[2]);
const char *file_name = argv[3];
struct sockaddr_in address;
bzero(&address, sizeof(address));
address.sin_family = AF_INET;
inet_pton(AF_INET, ip, &address.sin_addr);
address.sin_port = htons(port);
int sock = socket(PF_INET, SOCK_STREAM, 0);
assert(sock >= 0);
int ret = bind(sock, (struct sockaddr*)&address, sizeof(address));
assert(ret != -1);
ret = listen(sock, 5);
assert(ret != -1);
struct sockaddr_in client;
socklen_t client_addrlength = sizeof(client);
int connfd = accept(sock, (struct sockaddr*)&client, &client_addrlength);
if(connfd < 0){
printf("errno is : %d\n", errno);
}else{
char header_buf[BUFFER_SIZE];
memset(header_buf, '\0', BUFFER_SIZE);
char *file_buf;
struct stat file_stat;
bool valid = true;
int len = 0;
if(stat(file_name, &file_stat) < 0){
valid = false;
}else{
if(S_ISDIR(file_stat.st_mode)){
valid = false;
}else if(file_stat.st_mode & S_IROTH){
int fd = open(file_name, O_RDONLY);
file_buf = new char[file_stat.st_size + 1];
memset(file_buf, '\0', file_stat.st_size + 1);
if(read(fd, file_buf, file_stat.st_size) < 0){
valid = false;
}
}else{
valid = false;
}
}
if(valid){
ret = snprintf(header_buf, BUFFER_SIZE-1, "%s %s\r\n", "HTTP/1.1",
status_line[0]);
len += ret;
ret = snprintf(header_buf + len, BUFFER_SIZE-1-len,
"Content-Length: %d\r\n", file_stat.st_size);
len += ret;
ret = snprintf(header_buf + len, BUFFER_SIZE-1-len, "%s", "\r\n");
struct iovec iv[2];
iv[0].iov_base = header_buf;
iv[0].iov_len = strlen(header_buf);
iv[1].iov_base = file_buf;
iv[1].iov_len = file_stat.st_size;
ret = writev(connfd, iv, 2);
}else{
ret = snprintf(header_buf, BUFFER_SIZE-1, "%s %s\r\n",
"HTTP/1.1", status_line[1]);
len += ret;
ret = snprintf(header_buf + len, BUFFER_SIZE-1-len, "%s", "\r\n");
send(connfd, header_buf, strlen(header_buf), 0);
}
close(connfd);
delete[] file_buf;
}
close(sock);
return 0;
}
输出结果:
[root@localhost C]# telnet 192.168.91.128 5555
Trying 192.168.91.128...
Connected to 192.168.91.128.
Escape character is '^]'.
HTTP/1.1 200 OK
Content-Length: 270
#include <stdio.h>
int main(){
int input;
int flag = 1;
int count = 0;
scanf("%d",&input);
printf("input is %d\n", input);
while(flag){
if(input & flag){
count++;
}
flag <<= 1;
}
printf("the number has %d 1 in binary mode.\n", count);
return 0;
}
Connection closed by foreign host.完!

1652

被折叠的 条评论
为什么被折叠?



