注:本文所有代码均运行在Ubuntu6.06上
第一章三个例子
///第一个例子/
//gcc p8.c
/*socketpair 使用范例*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
int main(int argc, char *argv[])
{
int z;
int s[2];
//生成本地套接口对
z = socketpair(AF_LOCAL, SOCK_STREAM, 0, s);
if (z == -1)
{
fprintf(stderr, "%s: socketpair(AF_LOCAL, SOCK_STREAM, 0)/n", strerror(errno));
return 1;
}
//报告所返回的套接口文件描述符
printf("s[0] = %d;/n", s[0]);
printf("s[1] = %d;/n", s[1]);
system("netstat --unix -p");
return 0;
}
///第二个例子/
//gcc p11.c
/*
在套接口上实现I/O示例
结论:套接口可以双向传送信息,面且套接口的关闭方式与文件相同
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <string.h>
#include <errno.h>
int main(int argc, char **argv)
{
int z; //返回的状态码
int s[2]; //套接口对
char *cp; //工作指针
char buf[80]; //工作缓存区
//生成本地套接口对
z = socketpair(AF_LOCAL, SOCK_STREAM, 0, s);
if (z == -1)
{
fprintf(stderr, "%s: socketpair(AF_LOCAL, SOCK_STREAM, 0)/n", strerror(errno));
return 1;
}
//向套接口s[1]写入消息
z = write(s[1], cp = "hello?", 6);
if (z < 0)
{
fprintf(stderr, "%s:write(%d, /"%s/", %d)/n", strerror(errno), s[1], cp, strlen(cp));
return 2;
}
printf("wrote message: '%s' on s[1]/n", cp);
//向套接口s[0]读出消息
z = read(s[0], buf, sizeof(buf));
if (z < 0)
{
fprintf(stderr, "%s:read(%d, buf, %d)/n", strerror(errno), s[0], sizeof buf);
return 3;
}
buf[z] = 0;
printf("Received message '%s' from socket s[0]/n", buf);
z = write(s[0], cp = "Go away!", 8);
if (z < 0)
{
fprintf(stderr, "%s:write(%d, /"%s/", %d)/n", strerror(errno), s[0], cp, strlen(cp));
return 4;
}
printf("Wrote message '%s' on s[0]/n", cp);
z = read(s[1], buf, sizeof(buf));
if (z < 0)
{
fprintf(stderr, "%s:read(%d, buf, %d)/n", strerror(errno), s[1], sizeof buf);
return 3;
}
buf[z] = 0;
printf("Received message '%s' from socket s[1]/n", buf);
close(s[0]);
close(s[1]);
puts("Done.");
return 0;
}
///第三个例子/
//gcc p18.c
/*
使用socketpair和fork的客户/服务器示例
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <time.h>
#include <errno.h>
#include <sys/wait.h>
//以下已在sys/socket.h中定义,但有的LINUX(如redhat6.0)没有定义
#ifndef SHUT_WR
#define SHUT_RD 0
#define SHUT_WR 1
#define SHUT_RDWR 2
#endif
int main(int argc, char *argv[])
{
int z; //返回的状态码
int s[2]; //套接口对
char *msgp; //消息指针
int mlen; //消息长度
char buf[80]; //工作缓存区
pid_t chpid; //子进程PID
//生成本地套接口对
z = socketpair(AF_LOCAL, SOCK_STREAM, 0, s);
if (z == -1)
{
fprintf(stderr, "%s:socketpair(2)/n", strerror(errno));
exit(1);
}
//fork()调用后,生成两个进程
if ((chpid = fork()) == (pid_t)(-1))
{
fprintf(stderr, "%s:fork(2)/n", strerror(errno));
exit(1);
}else if (chpid == 0)
{
//子进程(客户)
char rxbuf[80]; //接收缓冲区
printf("Parent PID is %ld/n", (long)getppid());
close(s[0]); //服务器使用s[1]
s[0] = -1; //良好习惯
//形成消息并记录长度
//msgp = "%A %d-%b-%Y %l:%M %p";
msgp = "%d-%b-%y";
mlen = strlen(msgp);
printf("Child sending request '%s'/n", msgp);
fflush(stdout);
//向服务器写入请求
z = write(s[1], msgp, mlen);
if (z < 0)
{
fprintf(stderr, "%s:write(2)/n", strerror(errno));
exit(1);
}
//通过关闭套接口的写端说明不再向套接口写入任何消息
if (shutdown(s[1], SHUT_WR) == -1)
{
fprintf(stderr, "%s:shutdown(2)/n", strerror(errno));
exit(1);
}
//接收来自服务器的应答
z = read(s[1], rxbuf, sizeof(rxbuf));
if (z < 0)
{
fprintf(stderr, "%s:read(2)/n", strerror(errno));
exit(1);
}
//将来自服务器的消息末尾加入一个空字节
rxbuf[z] = 0;
//报告结果
printf("Server returned '%s'/n", rxbuf);
fflush(stdout);
close(s[1]); //关闭客户端
}else{
//父进程(服务器)
int status; //子进程终止状态码
char txbuf[80]; //应答缓冲区
time_t td; //现在的日期/时间
printf("Child PID is %ld/n", (long)chpid);
fflush(stdout);
close(s[1]); //客户使用s[1]
s[1] = -1; //良好的习惯
//等待来自客户的请求
z = read(s[0], buf, sizeof(buf));
if (z < 0)
{
fprintf(stderr, "%s:read(2)/n", strerror(errno));
exit(1);
}
//将来自客户的消息末尾加入一个空字节
buf[z] = 0;
//根据接收的请求实现服务器功能
time(&td); //获取现在的时间
strftime(txbuf, sizeof(txbuf), //缓冲区
buf, //输入格式
localtime(&td));//输入时间
//将结果发送给客户
z = write(s[0], txbuf, strlen(txbuf));
if (z < 0)
{
fprintf(stderr, "%s:write(2)/n", strerror(errno));
exit(1);
}
//关闭套接口
close(s[0]);
//等待子进程退出
waitpid(chpid, &status, 0);
}
return 0;
}