套接口编程理论基础:简单的TCP服务器程序

一个简单的回射服务器的步骤
1.客户端从标准输入读入一行文本,并写给服务器。
2.服务器端从网络输入读入这行文本,并返回给客户
3.客户端从网络输入读入这行反射文本,并显示在标准输出上。

如图:

服务器端的反射程序

#include    "unp.h"

int main(int argc, char **argv)
{
int listenfd, connfd;
pid_t childpid;
socklen_t clilen;
/*sockaddr_in为ipv4 套接口地址结构 详解参照3.2节*/
struct sockaddr_in cliaddr, servaddr;

/*Socket函数原型int socket (int family, int type, int protocol);protocol为0时
,以选择给定family和type组合的系统缺省值。参照 4.2节,
*/
listenfd = Socket(AF_INET, SOCK_STREAM, 0);

bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
/*考虑主机字节序和网络字节间的相互转换。参照3.4节*/
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);

/*把一个本地协议地址(&servaddr)赋予一个套接口(listenfd) 4.4节。赋予之前一定要先将(&servaddr)转
化成指向通用套接口地址结构的指针 3.2节。对于将地址转化成指向具体地址结构的指针可参照:将数值存储到指定的内存地址。
*/
Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));

/*listen把一个未连接的套接口转换成一个被动套接口,指示内核应该接受指向该套接口的连接请求。4.5节*/
Listen(listenfd, LISTENQ);

for ( ; ; ) {
clilen = sizeof(cliaddr);
/*Accept的第一个参数listenfd称为监听套接口描述字,是由socket创建;Accept的返回值connfd为已连接套接口描述字。4.6节*/
connfd = Accept(listenfd, (SA *) &cliaddr, &clilen);

if ( (childpid = Fork()) == 0) { /* child process */
Close(listenfd); /*child process close listening socket */
str_echo(connfd); /* process the request */
exit(0);
}
Close(connfd); /* parent closes connected socket */
}
}

将数值存储到指定的内存地址
  假设现在需要往内存 0x12ff7c地址上存入一个整型数 0x100。 我们怎么才能做到呢?我们知道可以通过一个指针向其指向的内存地址写入数据,那么这里的内存地址 0x12ff7c 其本质不就是一个指针嘛。所以我们可以用下面的方法:
int *p = (int *)0x12ff7c;/* p值则为0x12ff7c */
*p = 0x100;

TCP回射服务器程序:str_echo 函数

#include    "unp.h"

void
str_echo(int sockfd)
{
ssize_t n;
char buf[MAXLINE];

again:
while ( (n = read(sockfd, buf, MAXLINE)) > 0) /*从套接口读入数据*/
Writen(sockfd, buf, n); /*把内容返回给客户*/

if (n < 0 && errno == EINTR)
goto again;
else if (n < 0)
err_sys("str_echo: read error");
}



posted @ 2012-03-19 09:48  PoleStar  阅读(341)  评论(0编辑  收藏  举报