










一般情况下第一个样例都应该是简单并且容易让人产生兴趣的,但是UPN的第一个样例对于没有写过的人而言是第一个考验
由于官方代码大量使用 upn.h 头文件,经常会导致不知道函数从何而来
因此建议还是自己徒手编译
本样例需要用到的头文件如下(包括简单的说明):
#include <arpa/inet.h> //inet_ntop()、inet_ntoa()等 #include <memory.h> //memset #include <netinet/in.h> //struct sockaddr_in、PROTO_ICMP、INADDR_ANY等 #include <stdio.h> //printf #include <stdlib.h> //exit #include <sys/socket.h> //socket、bind、connect、struct sockaddr #include <sys/types.h> //类型定义 #include <time.h> //time #include <unistd.h> //read
本样例由两部分组成:服务端和用户端
尽管按照书上有 206.168.112.96 这个IP地址,不过在我的测试中并不能成功连接
因此,可以使用P5的代码实现客户端,用P10的代码实现服务端
由于服务端需要监听端口,因此该部分需要root权限
另外,服务端和客户端都应该是 htons(13) (htons和htonl存在区别)
设计到的几个函数定义如下
百度百科-socket
{% fold %}
int socket(int domain, int type, int protocol);int bind(SOCKET socket, const struct sockaddr* address, socklen_t address_len);函数原型:
int recv(SOCKET socket, char FAR* buf, int len, int flags);
参数说明:
返回值:
若无错误发生,recv()返回读入的字节数。如果连接已中止,返回0。否则的话,返回SOCKET_ERROR错误,应用程序可通过WSAGetLastError()获取相应错误代码。
函数原型:
ssize_t recvfrom(int sockfd, void buf, int len, unsigned int flags, struct socketaddr* from, socket_t* fromlen);
参数说明:
int sendto( SOCKET s, const char FAR* buf, int size, int flags, const struct sockaddr FAR* to, int tolen);int accept( int fd, struct socketaddr* addr, socklen_t* len);{% fold 点击现/隐代码 %}```c 服务端(需要管理员权限)
#include <arpa/inet.h> //inet_ntop()、inet_ntoa()等
#include <memory.h> //memset
#include <netinet/in.h> //struct sockaddr_in、PROTO_ICMP、INADDR_ANY等
#include <stdio.h> //printf
#include <stdlib.h> //exit
#include <sys/socket.h> //socket、bind、connect、struct sockaddr
#include <sys/types.h> //类型定义
#include <time.h> //time
#include <unistd.h> //read
#define MAXLINE 100
#define LISTENQ 1024
#define bzero(a, b) memset(a, 0, b)
void err(const char *_information) {
printf("%s\r\n", _information);
exit(0);
}
int main(int argc, char **argv) {
int listenfd, connfd;
struct sockaddr_in servaddr;
char buff[MAXLINE];
time_t ticks;
if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
err("socket error.");
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(13);
if (bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1)
err("bind error.");
if (listen(listenfd, LISTENQ) == -1)
err("Listen error.");
while (1) {
if ((connfd = accept(listenfd, (struct sockaddr *)NULL, NULL)) == -1)
err("accept error.");
ticks = time(NULL);
snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
if (write(connfd, buff, strlen(buff)) == -1)
err("write error.");
if (close(connfd) == -1)
err("close error.");
}
}
{% endfold %}
## 客户端
{% fold 点击现/隐代码 %}```c 客户端
#include <arpa/inet.h> //inet_ntop()、inet_ntoa()等
#include <memory.h> //memset
#include <netinet/in.h> //struct sockaddr_in、PROTO_ICMP、INADDR_ANY等
#include <stdio.h> //printf
#include <stdlib.h> //exit
#include <sys/socket.h> //socket、bind、connect、struct sockaddr
#include <sys/types.h> //类型定义
#include <time.h> //time
#include <unistd.h> //read
#define MAXLINE 100
#define bzero(a, b) memset(a, 0, b)
void err(const char *_information) {
printf("%s\r\n", _information);
exit(0);
}
int main(int argc, char **argv) {
int sockfd, n;
char recvline[MAXLINE + 1];
struct sockaddr_in servaddr;
//判断参数数目
if (argc != 2)
err("usage: a.out <IPaddress>");
//创建socket
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
err("socket error");
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(13);
//转换地址
if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
err("inet_pton error");
//连接
if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
err("connect error");
//读取
while ((n = read(sockfd, recvline, MAXLINE)) > 0) {
recvline[n] = 0;
if (fputs(recvline, stdout) == EOF)
err("fputs error");
}
if (n < 0)
err("read error");
exit(0);
}
{% endfold %}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。