23,118
社区成员
发帖
与我相关
我的任务
分享
//server.c
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
/* 服务器要监听的本地端口*/
#define MYPORT 4000
/* 能够同时接受多少没有accept 的连接*/
#define BACKLOG 10
int new_fd;
void sig_urg(int signo);
void main()
{
/* 在sock_fd 上进行监听,new_fd 接受新的连接*/
int sock_fd;
/* 用于存储以前系统缺省的SIGURL 处理器的变量*/ void * old_sig_urg_handle ;
/* 自己的地址信息*/
struct sockaddr_in my_addr;
/* 连接者的地址信息*/
struct sockaddr_in their_addr;
int sin_size;
int n ;
char buff[100] ;
int pid;
int new_id;
struct sigaction curract, oldact;
/* 这里就是我们一直强调的错误检查.如果调用socket() 出错,则返回*/
if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
/* 输出错误提示并退出*/
perror("socket");
exit(1);
}
/* 主机字节顺序*/
my_addr.sin_family = AF_INET;
/* 网络字节顺序,短整型*/
my_addr.sin_port = htons(MYPORT);
/* 将运行程序机器的IP 填充入s_addr */
my_addr.sin_addr.s_addr = INADDR_ANY;
/* 将此结构的其余空间清零*/
bzero(&(my_addr.sin_zero), 8);
/* 这里是我们一直强调的错误检查!! */
if (bind(sock_fd, (struct sockaddr *)&my_addr,sizeof(struct sockaddr)) == -1)
{
/* 如果调用bind()失败,则给出错误提示,退出*/
perror("bind");
exit(1);
}
/* 这里是我们一直强调的错误检查!! */
if (listen(sock_fd, BACKLOG) == -1)
{
/* 如果调用listen 失败,则给出错误提示,退出*/
perror("listen");
exit(1);
}
/* 设置SIGURG 的处理函数 sig_urg */
old_sig_urg_handle = signal(SIGURG, sig_urg);
/* 更改connfd 的属主*/
fcntl(sock_fd, F_SETOWN, getpid());
// curract.sa_handler = sig_urg;
// curract.sa_flags = 0;
// sigemptyset(&curract.sa_mask);
// sigaction(SIGURG, &curract, &oldact);
while(1)
{
/* 这里是主accept()循环*/
sin_size = sizeof(struct sockaddr_in);
/* 这里是我们一直强调的错误检查!! */
if ((new_fd = accept(sock_fd, (struct sockaddr *)&their_addr, &sin_size)) == -1)
{
perror("accept");
continue;
}
/* 服务器给出出现连接的信息*/
printf("server: got connection from %s\n", inet_ntoa(their_addr.sin_addr));
/* 这里将建立一个子进程来和刚刚建立的套接字进行通讯*/
pid = fork();
if(pid < 0) {
perror("fork error");
} else if (pid == 0) {
/* 这里是子进程*/
while(1)
{
if((n = recv(new_fd, buff, sizeof(buff) - 1, 0)) == 0)
{
printf("received EOF\n");
break ;
}
buff[n] = 0 ;
printf("Recv %d bytes: %s\n", n, buff);
}
}
if(pid > 0) {
/* 等待所有的子进程都退出*/
new_id = waitpid(-1, NULL, WNOHANG);
// sigaction(SIGURG, &oldact, NULL);
/* 恢复系统以前对SIGURG 的处理器*/
signal(SIGURG, old_sig_urg_handle);
/* 关闭new_fd 代表的这个套接字连接*/
close(new_fd);
}
}
}
void sig_urg(int signo)
{
int n;
char buff[100] ;
printf("SIGURG received\n");
n = recv(new_fd, buff, sizeof(buff) - 1, MSG_OOB);
buff [ n ] = 0 ;
printf("recv %d OOB byte: %s\n" , n,buff);
}
//client.c
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
/* 服务器程序监听的端口号*/
#define PORT 4000
/* 我们一次所能够接收的最大字节数*/
#define MAXDATASIZE 100
int main(int argc, char *argv[])
{
/* 套接字描述符*/
int sockfd, new_fd;
char buf[MAXDATASIZE];
struct hostent *he;
/* 连接者的主机信息*/
struct sockaddr_in their_addr;
/* 检查参数信息*/
if (argc != 2)
{
/* 如果没有参数,则给出使用方法后退出*/
fprintf(stderr,"usage: client hostname\n");
exit(1);
}
/* 取得主机信息*/
if ((he=gethostbyname(argv[1])) == NULL)
{
/* 如果gethostbyname()发生错误,则显示错误信息并退出*/
herror("gethostbyname");
exit(1);
}
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
/* 如果socket()调用出现错误则显示错误信息并退出*/
perror("socket");
exit(1);
}
/* 主机字节顺序*/
their_addr.sin_family = AF_INET;
/* 网络字节顺序,短整型*/
their_addr.sin_port = htons(PORT);
their_addr.sin_addr = *((struct in_addr *)he->h_addr);
printf("%s\n", inet_ntoa(*((struct in_addr *)he->h_addr)));
/* 将结构剩下的部分清零*/
bzero(&(their_addr.sin_zero), 8);
if((connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr))) == -1)
{
/* 如果connect()建立连接错误,则显示出错误信息,退出*/
perror("connect");
exit(1);
}
/* 这里就是我们说的错误检查! */
if (send(sockfd, "123", 3, 0) == -1)
{
/* 如果错误,则给出错误提示,然后关闭这个新连接,退出*/
perror("send");
close(sockfd);
exit(0);
}
printf("Send 3 byte of normal data\n");
/* 睡眠1 秒*/
sleep(1);
if (send(sockfd, "4", 1, MSG_OOB)== -1)
{
perror("send");
close(sockfd);
exit(0);
}
printf("Send 1 byte of OOB data\n");
sleep(1);
if (send(sockfd, "56", 2, 0) == -1)
{
perror("send");
close(sockfd);
exit(0);
}
printf("Send 2 bytes of normal data\n");
sleep(1);
if(send(sockfd,"7", 1, MSG_OOB)== -1)
{
perror("send");
close(sockfd);
exit(0);
}
printf("Send 1 byte of OOB data\n");
sleep(1);
if (send(sockfd, "89", 2, MSG_OOB)== -1)
{
perror("send");
close(sockfd);
exit(0);
}
printf("Send 2 bytes of normal data\n");
sleep(1);
close(sockfd);
return 0;
}