linux网络编程基础篇 一

概念一:Socket: a way to speak to other programs using standard Linux file descriptors.
概念二:Data Encapsulation:
1> a packet is born, the packet is wrapped ("encapsulated") in a header (and rarely a footer) by the first protocol (say, the TFTP protocol), then the whole thing (TFTP header included) is encapsulated again by the next protocol (say, UDP), then again by the next (IP), then again by the final protocol on the hardware (physical) layer (say, Ethernet).
2> When another computer receives the packet, the hardware strips the Ethernet header, the kernel strips the IP and UDP headers, the TFTP program strips the TFTP header, and it finally has the data.
Notes: you can write sockets programs that are exactly the same without caring how the data is physically transmitted (serial, thin Ethernet, AUI, whatever)
because programs on lower levels deal with it for you. The actual network hardware and topology is transparent to the socket programmer.
3> All you have to do for stream sockets is send() the data out. All you have to do for datagram sockets is encapsulate the packet in the method of your choosing and sendto() it out. The kernel builds the Transport Layer and Internet Layer on for you and the hardware does the Network Access Layer. Ah, modern technology.
概念三:字节序
1>there are two byte orderings: most significant byte (sometimes called an "octet") first, or least significant byte first. The former is called "Network Byte Order".(htons(), htonl()...)
概念四:常用结构体
struct sockaddr {
    unsigned short sa_family;    //address family, AF_xxx
    char           sa_data[14]; //14 bytes of protocol address
};
struct sockaddr_in {
    short int            sin_family;    //Address family
    unsigned short int    sin_port;    //Port number
    struct in_addr         sin_addr;    //Internet address
    unsigned char         sin_zero[8];//Same size as struct sockaddr
};
struct in_addr {
    unsigned long s_addr;     //load with inet_addr()
};
操作集(真的弄懂了吗?):
#系列一:结构体赋值
struct sockaddr_in my_addr;
//memset(&(my_addr.sin_zero), ’\0’, 8);
bzero(&my_addr, sizeof(my_addr));    //memset(&my_addr, 0, sizeof(my_addr));
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(PORTNUM);                    
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);    //inet_addr("127.0.0.1");

#系列二: socket API调用
1. socket(AF_INET, SOCK_STREAM, 0);    //listensd
2. bind(serversd, (struct sockaddr *) &my_addr, sizeof(my_addr));
3. listen(serversd, BACKLOG);
4. accept(serversd, (SA *) &their_addr, (socklen_t *) &size); //connectsd
5. close(sockfd);

#系列三: I/O调用
// writes up to count bytes from the buffer pointed buf to the file
// referred to by the file descriptor fd.
1. ssize_t write(int fd, const void *buf, size_t count);
// attempts to read up to count bytes from file descriptor fd into
// the buffer starting at buf.
2. ssize_t read (int fd, void *buf, size_t count);
3. ssize_t send (int sockfd, const void *msg, int len, int flags);
4. ssize_t recv (int sockfd, const void *msg, int len, int flags);

P.S.
1. endian.c    //测试机器是big endian || little endian 加深对概念理解
2. server.c    //面向连接C/S模式server端demo程序(多了个pthread下次blog再交流)
3. client.c(user-defined)//可以用"telnet"测试哈,具体使用方法manpage加互联网ok了.(最好用下netstat观察状态神马的)
3. 基础东西理解差不多了,组装起来也就形成所谓的"算法"了,重思想加实践.
4. 基础没你想象地那么容易,肯定也没那么难; 勤动脑,多动手, 基础基础。(利用好手头的工具:gcc|man|google|wikipedia stackoverflow|csdn etc.)
5. 过早关注细节,就容易陷进去了,就像"过早优化"一样, 正确的时间做正确的事情.
6. 欢迎大家批评指教
7. ...

/*
 *pthreadServer.c
 *gcc -o serverDemo pthreadServer.c -lpthread
 *Data: Friday 28 June 2013
*/ 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>

#define BACKLOG 5
#define BUFFERSIZE 2000
#define PORTNUM 8888
#define SA struct sockaddr

void Die(char *mess) {    perror(mess); exit(1); }    //error handler
void *connection_handler(void *);    //start function (pthread_create())

int
main(int argc, char *argv[])
{
    int serversd, connectsd, size;
    struct sockaddr_in my_addr, their_addr;
    pthread_t sniffer_thread;
    char *message;
  
    //Create a socket for server
    if ((serversd =  socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        Die("Failed to create socket");
    }

    //Prepare the sockaddr_in structure 
    bzero(&my_addr, sizeof(my_addr));    // Clear structure
    my_addr.sin_family = AF_INET;
    my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    my_addr.sin_port = htons(PORTNUM);

    //Bind the server socket
    if (bind(serversd, (SA *) &my_addr, sizeof(my_addr)) < 0) {
        Die("Failed to bind the server socket");
    }
    puts("bind done");

    //Listen on the server socket
    if (listen(serversd, BACKLOG) < 0) {
        Die("Failed to listen on the server");
    }

    //Accept the incoming connections
    puts("Waiting for incoming connection...");

    size = sizeof(struct sockaddr_in);
    while (1) {    //main accept() loop
        if ((connectsd = accept(serversd, (SA *) &their_addr, (socklen_t *) &size)) == -1) {
            perror("accept");
            continue;    
        }
        
        printf("server: got connection from %s\n", inet_ntoa(their_addr.sin_addr));
        
        if (pthread_create(&sniffer_thread, NULL, connection_handler, (void *) &connectsd) < 0) {
            Die("Could not create thread");
        }
        //puts("Handler assigned");
        //Now join the thread, so that we don't terminate before the thread
        //pthread_join(sniffer_thread, NULL);
    }
    close(serversd);
    exit(0);
}

//This will handle connection for each client
void *connection_handler(void *arg) {
    //Get the socket descriptor
    puts("Handler assigned");
    int sock = *(int *)arg;
    int read_size;
    char *message, buffer[BUFFERSIZE];

    //Send message to the client
    message = "I am your connection handler, now I shall repeat what you type\n";
    write(sock, message, strlen(message));

    //Receive response from client
    if ((read_size = recv(sock, buffer, BUFFERSIZE, 0)) < 0) {
        Die("Failed to receive initial bytes from client");
    }
    while (read_size > 0) {
        if (send(sock, buffer, read_size, 0) != read_size) {
            Die("Failed to send bytes to client");
        }
        if ((read_size = recv(sock, buffer, BUFFERSIZE, 0)) < 0) {
            Die("Failed to receive additional bytes from client");
        }
    }

    close(sock);

    return;
}
//endian.c
#include <stdio.h>

int
main(void)
{
    int i;                                //Loop variable
    long x= 0x12345A80;                    //Value to play with
    unsigned char* ptr = (char*) &x;    //Byte pointer

    //Oberser value in host byte order
    printf("In the host byte order:\n");
    printf("x in hex: %x\n", x);
    printf("x by bytes: ");

    for (i = 0; i < sizeof(long); i++) {
        printf("%x\t", ptr[i]);
    }
    printf("\n");

    //Oberser value in network byte order
    x = htonl(x);
    printf("\nAfter htonl()\n");
    printf("x in hex: %x\n", x);
    printf("x by bytes: ");
    
    for (i = 0; i < sizeof(long); i++) {
        printf("%x\t", ptr[i]);
    }
    printf("\n");
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值