网络程序设计 - 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
}
}
}
}
题外话:金秋