对于linux的服务器编程而言,几个基本的api是必备的,算起来攻读linux也有一段时间了,但是却没有将反思记录下来形成文字。
网络编程底层的API相对固定也比较容易 理解,最近写的是一个利用SOCK_STREAM也就是TCP链接的SOCKE通信测试, 只是个框架,没有实质内容,但就是因为简单才能一眼看出主要的API函数。
server.c
<pre name="code" class="cpp">#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXLINE 80
#define SERV_PORT 1234
int main()
{
const char *ip = "127.0.0.1";
struct sockaddr_in seraddr, cliaddr;
socklen_t cliaddr_len;
int listenfd, connfd;
char buff[MAXLINE];
char str[INET_ADDRSTRLEN];
int i, n;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
bzero(&seraddr, sizeof(seraddr));
seraddr.sin_family = AF_INET;
// seraddr.sin_addr.s_addr = htonl(INADDR_ANY);
inet_pton(AF_INET, ip, &seraddr.sin_addr);
seraddr.sin_port = htons(SERV_PORT);
bind(listenfd, (struct sockaddr *)&seraddr, sizeof(seraddr));
listen(listenfd, 20);
printf("begin acceptting...\n");
while(1)
{
cliaddr_len = sizeof(cliaddr);
connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len);
recv(connfd, buff, sizeof(buff), 0);
printf("%s\n", buff);
close(connfd);
}
close(listenfd);
return 0;
}
client.c
<pre name="code" class="cpp">#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define MAXLINE 80
#define PORT 1234
int main(int argc, char **argv)
{
const char *ip = "127.0.0.1";
struct sockaddr_in seraddr;
char buf[MAXLINE];
int sockfd, n;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
seraddr.sin_family = AF_INET;
inet_pton(AF_INET, ip, &seraddr.sin_addr);
seraddr.sin_port = htons(PORT);
connect(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr));
char *str = argv[1];
strcpy(buf, str);
send(sockfd, buf, sizeof(buf), 0);
close(sockfd);
return 0;
}
~
~
以上 是两个最简单的通信的例子,谈不上逻辑,不过至少能看出API之间的调用关系。
网络之间的通信涉及到不同主机间的交互,而字节在不同操作系统中的存储有大端和小端之分。32位的CPU一次处理4个字节,64位的CPU一次处理6B, 但这4B/8B在地址空间的存储却有大端和小端之分。利用下面的程序可以区分出大小端
#include <stdio.h>
void byteorder()
{
union
{
short value;
char union_bytes[sizeof(short)];
}test;
test.value = 0x0102;
if( (test.union_bytes[0] == 1) && (test.union_bytes[2] == 2) )
{
printf("big\n");
}
else if( (test.union_bytes[0] == 2) && (test.union_bytes[1] == 1) )
{
printf("little\n");
}
else
{
printf("unknown\n");
}
}
int main()
{
byteorder();
return 0;
}