Tinyhttpd實戰二:簡單socket編程實踐

簡單socket編程實踐

//client.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>
#include <netinet/tcp.h>
#include <netdb.h>


int main(int argc, const char * argv[]) {
    // insert code here...
    printf("Hello, World!\n");
    
    int client_sockfd;
    int len;
    struct sockaddr_in remota_addr; //服務器端網絡地址結構體
    char buf[BUFSIZ];  //數據傳送的緩衝區
    memset(&remota_addr,0,sizeof(remota_addr)); //數據初始化--清零
    remota_addr.sin_family = AF_INET;  //設置爲IPV4通信
    remota_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    remota_addr.sin_port = htons(8000); //服務器端口號
    
    //創建客戶端套接字--Ipv4協議,面向連接通信,TCP協議
    //成功,返回0 ,失敗返回-1
    if ((client_sockfd=socket(PF_INET, SOCK_STREAM, 0))<0) {
        perror("socket");
        return 1;
    }
    
    //將套接字綁定到服務器的網絡地址上
    if (connect(client_sockfd, (struct sockaddr *)&remota_addr, sizeof(struct sockaddr))<0) {
        perror("connect");
        return 1;
    }
    
    printf("connect to server\n");
    
    len = recv(client_sockfd, buf, BUFSIZ, 0); //接受服務器端消息
    buf[len]='\0';
    printf("%s\n",buf);  //打印服務器端消息
    
    //循環的發送信息並打印接受消息--recv返回接收到的字節數,send返回發送的字節數
    while (1) {
        printf("Enter string to send:");
        scanf("%s",buf);
        if (!strcmp(buf,"quit")) {
            break;
        }
        
        len=send(client_sockfd,buf,strlen(buf),0);
        len=recv(client_sockfd,buf,BUFSIZ,0);
        buf[len]='\0';
        printf("received:%s\n",buf);
        
    }
    
    close(client_sockfd);
    
    return 0;
}

//server.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>
#include <netinet/tcp.h>
#include <netdb.h>
#include <errno.h>

int main(int argc, const char * argv[]) {
    // insert code here...
    printf("Hello, World!\n");
    
    int server_sockfd; //服務端套接字
    int client_sockfd; //客戶端套接字
    int len;
    struct sockaddr_in my_add; //服務器網絡地址結構體
    struct sockaddr_in remote_addr; //客戶端網絡地址結構體
    socklen_t sin_size;
    char buf[BUFSIZ]; //數據傳送的緩衝區
    memset(&my_add,0,sizeof(my_add)); //數據初始化--清零
    my_add.sin_family = AF_INET; //設置爲IP通信
    my_add.sin_addr.s_addr = INADDR_ANY; //服務器IP地址--允許連接到所有本地地址上
    my_add.sin_port = htons(8000); //服務器端口號
    
    //創建服務器端套接字--IPV4協議 ,面向連接通信,TCP協議
    if((server_sockfd=socket(PF_INET, SOCK_STREAM, 0))<0) {
        perror("socket");
        return 1;
    }
    
    //將套接字綁定到服務器的網絡地址上
    if (bind(server_sockfd, (struct sockaddr *)&my_add, sizeof(struct sockaddr))<0) {
        perror("bind");
        return 1;
    }
    
    //監聽連接請求--監聽隊列長度爲5
    listen(server_sockfd, 5);
    sin_size = sizeof(struct sockaddr_in);
    
    //等待客戶端連接請求到達
    if ((client_sockfd=accept(server_sockfd, (struct sockaddr *)&remote_addr, &sin_size))<0) {
        perror("accept");
        return 1;
    }
    
    printf("accept client %s\n",inet_ntoa(remote_addr.sin_addr));
    len = send(client_sockfd, "welcome to my server", 21, 0); //發送歡迎信息
    
    //接受客戶端的數據並將其發送給客戶端--recv返回接收到的字節數,send返回發送的字節數
    while ((len=recv(client_sockfd, buf, BUFSIZ, 0))>0) {
        buf[len]='\0';
        printf("receive:%s\n",buf);
        if (send(client_sockfd, buf, len, 0)<0) {
            perror("write");
            return 1;
        }
    }
    
    close(client_sockfd);
    close(server_sockfd);
    
    return 0;
}

//Makefile
all: server client
LIBS = -lpthread 
httpd: server.c
	gcc -g -W -Wall -pthread $(LIBS) -o $@ $<

client: client.c
	gcc -W -Wall -o $@ $<
clean:
	rm server client

運行截圖

客戶端
在這裏插入圖片描述
服務端
在這裏插入圖片描述

發佈了48 篇原創文章 · 獲贊 8 · 訪問量 1893
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章