网络程序设计 - 2020秋复习材料
以下为一些典型的程序段,课本中的错误已经纠正,有助于复习
参考教材《网络应用程序设计》 方敏
只写出了关键的程序段,为了应对考试也可以多写几遍,加深印象
// 定义一个套接字地址
struct sockaddr_in my_addr;
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(8080);
//1
my_addr.sin_addr.s_addr = inet_addr("192.168.1.1");
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
inet_aton("192.168.1.1", &my_addr.sin_addr);
// 输出一个点分十进制地址
char *a1;
a1 = inet_ntoa(my_addr.sin_addr);
printf("%s", a1);
// TCP server
int server_fd, client_fd;
server_fd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in servaddr, remote_addr;
bzero(&servaddr, sizeof(struct sockaddr));
bzero(&remote_addr, sizeof(struct sockaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(3000);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
// 其他写法
servaddr.sin_addr.s_addr = inet_addr("192.168.1.1");
inet.aton("192.168.1.1", &servaddr.sin_addr);
//
bind(server_fd, (struct sockaddr*)&servaddr, sizeof(struct sockaddr));
listen(server_fd, 20);
while(1)
{
int addrlen = sizeof(struct sockaddr);
client_fd = accept(server_fd, (struct sockaddr*)&remote_addr, &addrlen);
// 阻塞
if(!fork()) //子进程
{
char a1 = inet_ntoa(remote_addr.sin_addr);
printf("收到来自%s:%d",a1, ntohs(remote_addr.sin_port));
// 发送Hello
send(client_fd, "hello", 5, 0);
}
}
// TCP Client
int client_fd;
char buf[1024];
struct sockaddr_in remote_addr;
remote_addr.sin_family = AF_INET;
remote_addr.sin_port = htons(3000);
remote_addr.sin_addr.s_addr = inet_addr("192.168.1.1");
client_fd = socket(AF_INET, SOCK_STREAM, 0);
connect(client_fd, (struct sockaddr*)&remote_addr, sizeof(struct sockaddr));
read(client_fd, buffer, 1024);
printf("%s",buffer);
// 设为非阻塞
int flags;
flags = fcntl(sock_fd, F_GETFL, 0);
flags |= O_NONBLOCL;
fcntl(sock_fd, F_SETFL, flags);
int flags;
flags = fcntl(sock_fd, F_GETFL, 0);
flags &= ~O_NONBLOCK;
fcntl(sock_fd, F_SETFL, flags);
// 宿主
pid = fcntl(sock_fd, F_GETOWN, 0);
// 多路复用
// fd1
struct fd_set exs;
FD_SET(fd1, &exs);
// FD_CLR
// FD_ZERO
// FD_ISSET
select(fd1+1, NULL, NULL, &exs);// 阻塞,直到有fd就绪
// UDP
sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in to_addr;
bzero(&to_addr, sizeof(struct sockaddr));
sendto(sock_fd, "hello", 5, 0, (struct sockaddr*)&to_addr, sizeof(struct sockaddr));
recvfrom(sock_fd, buf, 1024, 0, NULL, NULL)
// UDP超时重发 SIGALARM
int timeout;
void sighandler()
{
timeout = 1;
}
struct sigaction act;
act.sa_handler = sighandler;
signalaction(SIGALARM, &act, NULL);
while(1)
{
timeout = 0;
alarm(20); // 20s
// 阻塞
n = recvfrom(fd, buf, 1024, 0, (struct sockaddr*)&from_addr, sizeof(struct sockaddr));
if(n == -1 && errno == EINTR) // 中断发生
{
if(timeout == 1)
{
// 重发
proc_timeout();
continue;
}
}
}
void proc_timeout()
{
// 重发
}
// 预创建10个子进程的TCP并发服务器
#define CLDNUM 10
int main()
{
int listenfd, connfd;
int pid[CLDNUM];
struct sockaddr_in servaddr;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
// bind
listen(listenfd, 10);
// 关键
for(i=0;i<CLDNUM;I++)
{
// 子进程
if((pid[i] = fork()) == 0) {
// 循环服务器
while(1)
{
accept
}
}
}
}
题外话:金秋
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现