1.linux下socket 网络编程(客户端向服务器端发送文件) 求源代码 大哥大姐帮帮忙 。源码。源码谢谢
2.Linux系统编程 每周一深入 (二)高级文件IO
3.fopen在+r+rb+方式打开文件后+fread的源码区
4.Linux系统命令中exit与exit的区别
5.怎么把文本文件的内容作为可执行文件的输入数据
linux下socket 网络编程(客户端向服务器端发送文件) 求源代码 大哥大姐帮帮忙 。。源码谢谢
server:
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <syslog.h>
#include <sys/time.h>
#include <string.h>
#include <fcntl.h>
#include <sys/wait.h>
#define MAXDATASIZE
#define SERVPORT
#define BACKLOG
int SendFileToServ(const char *path,源码 const char *FileName, const char *ip)
{
#define PORT
int sockfd;
int recvbytes;
char buf[MAXDATASIZE];
char send_str[MAXDATASIZE];
char filepath[] = { 0};
struct sockaddr_in serv_addr;
FILE *fp;
sprintf(filepath, "%s%s", path, FileName);
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
perror("socket");
return 1;
}
bzero(&serv_addr,sizeof(struct sockaddr_in));
serv_addr.sin_family=AF_INET;
serv_addr.sin_port=htons(PORT);
inet_aton(ip, &serv_addr.sin_addr);
int IErrCount = 0;
again:
if(connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(struct sockaddr))==-1)
{
if (5 == IErrCount)
return 1;
IErrCount++;
perror("connect");
sleep(2);
goto again;
}
//if ((fp = fopen(FileName, "rb")) == NULL)
if ((fp = fopen(filepath, "rb")) == NULL)
{
perror("fopen ");
return 1;
}
recvbytes = write(sockfd, FileName, strlen(FileName));
recvbytes = read(sockfd, buf, MAXDATASIZE);
if (!memcmp(buf, "sendmsg", 7))
{
while(fgets(send_str, MAXDATASIZE, fp))
{
recvbytes = write(sockfd, send_str, strlen(send_str));
recvbytes = read(sockfd, buf, MAXDATASIZE);
if (recvbytes <= 0)
{
fclose(fp);
close(sockfd);
return 1;
}
if (memcmp(buf, "goon", 4))
{
fclose(fp);
close(sockfd);
return 1;
}
}
recvbytes = write(sockfd, "end", 3);
}
else
{
fclose(fp);
close(sockfd);
return 1;
}
memset(buf, 0, MAXDATASIZE);
if (read(sockfd, buf, MAXDATASIZE) <= 0)
{
close(sockfd);
return 2;
}
char *Eptr = "nginx reload error";
//printf("bf[%s]\n", buf);
int ret;
ret = strncmp(buf, Eptr, strlen(Eptr));
//printf("%d\n", ret);
if (!ret)
{
close(sockfd);
return 2;
}
close(sockfd);
return 0;
}
int mysyslog(const char * msg)
{
FILE *fp;
if ((fp = fopen("/tmp/tmp.log", "a+")) == NULL)
{
return 0;
}
fprintf(fp, "[%s]\n", msg);
fclose(fp);
return 0;
}
static void quit_handler(int signal)
{
kill(0, SIGUSR2);
syslog( LOG_NOTICE, "apuserv quit...");
// do something exit thing ,such as close socket ,close mysql,free list
// .....
//i end
exit(0);
}
static int re_conf = 0;
static void reconf_handler(int signal)
{
re_conf=1;
syslog(LOG_NOTICE,"apuserv reload configure file .");
// 请在循环体中判断,如果re_conf == 1,源码k线的公式源码请再次加载配置文件。源码
}
static int isrunning(void)
{
int fd;
int ret;
struct flock lock;
lock.l_type = F_WRLCK;
lock.l_whence = 0;
lock.l_start = 0;
lock.l_len = 0;
const char *lckfile = "/tmp/apuserv.lock";
fd = open(lckfile,源码O_WRONLY|O_CREAT);
if (fd < 0) {
syslog(LOG_ERR,"can not create lock file: %s\n",lckfile);
return 1;
}
if ((ret = fcntl(fd,F_SETLK,&lock)) < 0) {
ret = fcntl(fd,F_GETLK,&lock);
if (lock.l_type != F_UNLCK) {
close(fd);
return lock.l_pid;
}
else {
fcntl(fd,F_SETLK,&lock);
}
}
return 0;
}
int MyHandleBuff(const char *buf, char *str, char *FileName, char *pth)
{
sscanf(buf, "%s %s %s", pth, FileName, str);
printf("path=%s\nfilename=%s\nip=%s\n", pth, FileName, str);
return 0;
}
int main(int argc, char **argv)
{
int sockfd,client_fd;
socklen_t sin_size;
struct sockaddr_in my_addr,remote_addr;
char buff[MAXDATASIZE];
int recvbytes;
#if 1
int pid ;
char ch ;
int ret;
int debug = 0;
signal(SIGUSR1, SIG_IGN);
signal(SIGUSR2, SIG_IGN);
signal(SIGHUP, SIG_IGN);
signal(SIGTERM, quit_handler);
syslog(LOG_NOTICE,"apuserver start....");
while ((ch = getopt(argc, argv, "dhV")) != -1) {
switch (ch) {
case 'd':
debug = 1;
break;
case 'V':
printf("Version:%s\n","1.0.0");
return 0;
case 'h':
printf(" -d use daemon mode\n");
printf(" -V show version\n");
return 0;
default:
printf(" -d use daemon mode\n");
printf(" -V show version\n");
}
}
if (debug && daemon(0,0 ) ) {
return -1;
}
if (isrunning()) {
fprintf(stderr, "apuserv is already running\n");
syslog(LOG_INFO,"apuserv is already running\n");
exit(0);
}
while (1) {
pid = fork();
if (pid < 0)
return -1;
if (pid == 0)
break;
while ((ret = waitpid(pid, NULL, 0)) != pid) {
syslog(LOG_NOTICE, "waitpid want %d, but got %d", pid, ret);
if (ret < 0)
syslog(LOG_NOTICE, "waitpid errno:%d", errno);
}
kill(0, SIGUSR2);
sleep(1);
syslog(LOG_NOTICE,"restart apuserver");
}
signal(SIGHUP, reconf_handler);
signal(SIGPIPE, SIG_IGN);
signal(SIGUSR1,SIG_IGN);
signal(SIGUSR2, SIG_DFL);
signal(SIGTERM, SIG_DFL);
#endif
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
perror("socket");
exit(1);
}
bzero(&my_addr,sizeof(struct sockaddr_in));
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(SERVPORT);
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))==-1)
{
perror("bind");
exit(1);
}
if(listen(sockfd,BACKLOG)==-1)
{
perror("listen");
exit(1);
}
int nret;
while(1)
{
sin_size = sizeof(struct sockaddr_in);
if((client_fd = accept(sockfd, (struct sockaddr *)&remote_addr, &sin_size))==-1)
{
perror("falied accept");
continue;
}
memset(buff, 0, MAXDATASIZE);
recvbytes = read(client_fd, buff, MAXDATASIZE);
char str[] = { 0};
char FileName[] = { 0};
char path[] = { 0};
MyHandleBuff(buff, str, FileName, path);
if (recvbytes > 0)
{
nret = SendFileToServ(path, FileName, str);
printf("nret[%d]\n", nret);
if (1 == nret)
write(client_fd, "send file error", );
else if(2 == nret)
write(client_fd, "reload nginx error", );
else
write(client_fd, "succ", 4);
}
close(client_fd);
}
}
_________________________________________________
client:
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <syslog.h>
#include <sys/time.h>
#include <string.h>
#include <fcntl.h>
#include <sys/wait.h>
#define MAXDATASIZE
#define SERVPORT
#define BACKLOG
int mysyslog(const char * msg)
{
FILE *fp;
if ((fp = fopen("/tmp/tmp.log", "a+")) == NULL)
{
return 0;
}
fprintf(fp, "[%s]\n", msg);
fclose(fp);
return 0;
}
static void quit_handler(int signal)
{
kill(0, SIGUSR2);
syslog( LOG_NOTICE, "apuserv quit...");
// do something exit thing ,such as close socket ,close mysql,free list
// .....
//i end
exit(0);
}
static int re_conf = 0;
static void reconf_handler(int signal)
{
re_conf=1;
syslog(LOG_NOTICE,"apuserv reload configure file .");
// ·?1nf == 1£?′μ?
static int isrunning(void)
{
int fd;
int ret;
struct flock lock;
lock.l_type = F_WRLCK;
lock.l_whence = 0;
lock.l_start = 0;
lock.l_len = 0;
const char *lckfile = "/tmp/dstserver.lock";
fd = open(lckfile,O_WRONLY|O_CREAT);
if (fd < 0) {
syslog(LOG_ERR,"can not create lock file: %s\n",lckfile);
return 1;
}
if ((ret = fcntl(fd,F_SETLK,&lock)) < 0) {
ret = fcntl(fd,F_GETLK,&lock);
if (lock.l_type != F_UNLCK) {
close(fd);
return lock.l_pid;
}
else {
fcntl(fd,F_SETLK,&lock);
}
}
return 0;
}
int main(int argc, char **argv)
{
int sockfd,client_fd;
socklen_t sin_size;
struct sockaddr_in my_addr,remote_addr;
char buff[MAXDATASIZE];
int recvbytes;
#if 1
int pid ;
char ch ;
int ret;
int debug = 0;
signal(SIGUSR1, SIG_IGN);
signal(SIGUSR2, SIG_IGN);
signal(SIGHUP, SIG_IGN);
signal(SIGTERM, quit_handler);
syslog(LOG_NOTICE,"dstserver start....");
while ((ch = getopt(argc, argv, "dhV")) != -1) {
switch (ch) {
case 'd':
debug = 1;
break;
case 'V':
printf("Version:%s\n","1.0.0");
return 0;
case 'h':
printf(" -d use daemon mode\n");
printf(" -V show version\n");
return 0;
default:
printf(" -d use daemon mode\n");
printf(" -V show version\n");
}
}
if (debug && daemon(0,0 ) ) {
return -1;
}
if (isrunning()) {
fprintf(stderr, "dstserver is already running\n");
syslog(LOG_INFO,"dstserver is already running\n");
exit(0);
}
while (1) {
pid = fork();
if (pid < 0)
return -1;
if (pid == 0)
break;
while ((ret = waitpid(pid, NULL, 0)) != pid) {
syslog(LOG_NOTICE, "waitpid want %d, but got %d", pid, ret);
if (ret < 0)
syslog(LOG_NOTICE, "waitpid errno:%d", errno);
}
kill(0, SIGUSR2);
sleep(1);
syslog(LOG_NOTICE,"restart apuserver");
}
signal(SIGHUP, reconf_handler);
signal(SIGPIPE, SIG_IGN);
signal(SIGUSR1,SIG_IGN);
signal(SIGUSR2, SIG_DFL);
signal(SIGTERM, SIG_DFL);
#endif
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
perror("socket");
exit(1);
}
bzero(&my_addr,sizeof(struct sockaddr_in));
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(SERVPORT);
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))==-1)
{
perror("bind");
exit(1);
}
if(listen(sockfd,BACKLOG)==-1)
{
perror("listen");
exit(1);
}
char filepath[MAXDATASIZE]= { 0};
FILE *fp;
while(1)
{
sin_size = sizeof(struct sockaddr_in);
if((client_fd = accept(sockfd, (struct sockaddr *)&remote_addr, &sin_size))==-1)
{
perror("falied accept");
continue;
}
memset(buff, 0, MAXDATASIZE);
recvbytes = read(client_fd, buff, MAXDATASIZE);
sprintf(filepath, "/etc/nginx/url_rule/%s", buff);
if ((fp = fopen(filepath, "wb")) == NULL)
{
perror("fopen");
close(client_fd);
continue;
}
write(client_fd, "sendmsg", 7);
while(read(client_fd, buff, MAXDATASIZE))
{
if (!memcmp(buff, "end", 3))
{
fclose(fp);
break;
}
else
{
fprintf(fp, "%s", buff);
write(client_fd, "goon", 4);
}
}
//system("nginx -s reload");
char *Sptr = "nginx reload succ";
char *Eptr = "nginx reload error";
int ret;
ret = system("nginx -s reload");
printf("ret[%d]\n", ret);
if (ret != 0)
{
write(client_fd, Eptr, strlen(Eptr));
}
else
{
write(client_fd, Sptr, strlen(Sptr));
}
close(client_fd);
}
}
以前写的:内容忘记了。不是源码很复杂你可以自己看!
Linux系统编程 每周一深入 (二)高级文件IO
在Linux系统中,源码一切操作都可以抽象为文件读写。源码因此,源码本系列文章的源码第二部分将深入探讨Linux中的文件IO。
常规的源码文件IO涉及的系统调用包括:open、read、源码write、close,分别对应打开、读取、写入和关闭文件。在执行读写操作时,内核会维护一个指向当前文件偏移量的指针。为了灵活控制偏移量,系统调用lseek提供了定位文件位置的能力。glibc提供的fopen、fread、fwrite、close和fseek(ftell)等函数,则是上述系统调用的封装,其中包含缓存机制以提高读写效率。
通常,上述函数足以应对大部分应用场景。今天,我们将重点介绍几个更高级的系统调用:pread、pwrite、readv、writev、preadv和pwritev。蜜蜂宝源码它们的功能可以用基本读写函数实现,但提供更便捷的特性,可能在某些场景下成为提高效率的利器。
以多线程下载程序为例,我们可以通过记录每个线程负责的文件部分位置和已写入字节数,实现数据合并。但这种方法可能因加锁和频繁的lseek操作而成为下载速度的瓶颈。为了避免这些问题,可以使用pread和pwrite系统调用,它们不会改变文件偏移量,从而简化程序逻辑。
在分散读和集中写的场景中,writev系统调用可以将分散数据集中在一次系统调用中发送。与之对应的readv系统调用则完成相反的操作,从文件中读取数据并填充到指定位置。nginx源码中就包含分散度和集中写的例子。
此外,Linux还提供了preadv和pwritev函数,支持多线程的分散读和集中写。这些函数结合了pread、pwrite、readv和writev的功能,在特定应用场景下可以提高效率。
总结:Linux的文件IO功能丰富,除了基础操作外,还针对多线程和集中/分散读写提供了系列函数。掌握这些函数的用途和使用方法,将有助于解决特定应用场景下的效率问题。
fopen在+r+rb+方式打开文件后+fread的区
fopen在“r”“rb”方式打开文件后,fread的区别
年月 - FILE *test = fopen("test.bmp", "r"); memset(buffer, 0XFF, ); fread(buffer, 1,
用fopen打开文件时,r和rb的区别
年月 - r是打开字符文件 rb是打开二进制文件 那怎么区分是字符文件还是二进制文件? 如果是二进制文件用r打开会出错吗?
C中fopen打开方式r和rb的区别
年月 - [8] = { 0}; FILE* fp = fopen("png.png", "r"); fread(buffer, 8, 1, fp); fclose(fp);那么8个字节是: 4E 0A
简单的问:fopen中打开的参数,r同rb的区别?
h模式是从十字军的试炼(toc)开始才有的(也就是说,在toc之前的uld,naxx,以及整个tbc和之前的所有副本都没有h本,只有打本人数的区别,人,人,一梦源码人,人这样子),在这之前,装备的模型以及配色可能会由于或者xy人模式的不同而有所不同(主要体现在uld和naxx,tbc包括之前的本没区别)。不管如何,一些4年以上的老玩家,这个过程是的第一部分第二部分比较深刻,也是就是为什么喜欢的年代的主要原因,那个时候一切的新奇的,而且团队努力的过程也是一个平民向精英化过度的过程,t3一套给人感觉是神秘和羡慕,“人家是如何打本啊~~”正如此过程二就区分很,tbc后很都着急,着急穿上那些曾经代表荣誉的套装,着急穿上那些曾经区分所谓高玩和低玩的标志,着急穿上曾经无数人希望却可遇不可求的东西,本来blz设计思路是就全民体验fb化,由于没有困难模式,因此fb越来越简单,但是那些着急的人们不知道,当他们能轻松穿上以前身份装的时候,其实这个身份装的区别性早就消失了。当你没有使用new关键字调用函数时,此处只是一个函数表达式,表示对象的引用,该函数的属性其实是挂载在window对象下面的,由检测也可知,注意这是在非严格模式下的,严格模式则该this并不指向任何谁,返回一个undefined值,若添加属性是会报错的,对于普通函数调用前,若无new关键字,则它并没有实例化(创建)一个对象,该this值并不指向该创建的对象,若有new构造器函数的调用,在使用上与内置构造器上并无多大的区别,有new和无new函数的调用,是有很大的区别的,个人建议即使是在使用内置构造函数时,也不要省略该new关键字,并且构造函数的首字目大写,这一点沿袭了内置构造函数的特征,主要是为了区分与普通函数的区别,警示我们这是构造函数,实例出的对象,也就是创建了模板啊,具体构造函数细节在以后文章中详谈,下面是正确是使用new函数的调用,实现模板创建的过程,示例代码如下:
fopen函数以‘rb’模式 和 ‘r’ 模式打开文件的不同
年月 - 模式打开文件。 乱码是多余的垃圾值(初始化时赋的初始值)。ftell()返回值比fread()返回值大。fread返回实际得到的字符数,正常情况文本文件中\r\n读取后变成了\n,这就会导致读取
fread "rb"与"r","wb","w"的区别
年月 - 在fread时,"rb"与"r"对某些字符作用,是不同的;文本模式和二进制模式读取不一样的文本:读: 遇到回车-换行(0D 0A),就会转换为换行符0A 写:遇到
fread "rb"与"r","wb","w"的区别
年月 - 在fread时,"rb"与"r"对某些字符作用,是不同的;文本模式和二进制模式读取不一样的文本:读: 遇到回车-换行(0D 0A
fread读文件(rb方式fopen),怎样识别字符串中的源码冻结期换行符和回车符
年月 - 我通过fopen打开文件(rb方式),我要通过识别文件中的回车符和换行符来决定其他函数的调用,但是*szBuf == '\t'和*szBuf == '\n'都不能正确判断,请问我该怎么识别回车
使用fread读取二进制文件时,一定打开的时候使用‘rb’,不要只写r
年月 - 调了那么久,其实就是fopen时候不能只写‘r’,还要写‘rb’。 不然会造成fread读不完指定的字节数。也就是说如果是linux上的程序,r和rb没有什么区别
python打开文件时'w'与'wb'的区别,'r'与'rb'的区别
年月 - ') f.close() 文本w方式写入时, 遇到\n自动替换成\r\n,以二进制文本读: >> > f = open('./abcd', 'rb') >> > print
fopen在“r”“rb”方式打开文件后,fread的区别
年月 - FILE *test = fopen("test.bmp", "r"); memset(buffer, 0XFF, ); fread(buffer, 1,
用fopen打开文件时,r和rb的区别
用eclipse编译没有问题,用ant编译出现此错误 用ultraedit打开文件,ctrl+h,可以查看进制编码,发现文件首位果然有两个字符,正常打开是看不见的 他是带bom的utf-8格式 用ultraedit另存为一下,编码选择utf-8无bom即可解决此问题。1. 被写入的文件可以用、写、读写,追加方式打开,用写或读写方式打开一个已存在的文件时将清除原有的文件内容,写入字符从文件首开始。1) 被写入的文件可以用写、读写、追加方式打开,用写或读写方式打开一个已存在的文件时将清除原有的文件内容,写入字符从文件首开始。
C中fopen打开方式r和rb的区别
年月 - [8] = { 0}; FILE* fp = fopen("png.png", "r"); fread(buffer, 8, 1, fp); fclose(fp);那么8个字节是: 4E 0A
简单的问:fopen中打开的参数,r同rb的区别?
h模式是从十字军的试炼(toc)开始才有的(也就是说,在toc之前的uld,naxx,以及整个tbc和之前的所有副本都没有h本,只有打本人数的区别,人,人,人,人这样子),在这之前,装备的模型以及配色可能会由于或者xy人模式的不同而有所不同(主要体现在uld和naxx,tbc包括之前的本没区别)。不管如何,一些4年以上的11000101的源码老玩家,这个过程是的第一部分第二部分比较深刻,也是就是为什么喜欢的年代的主要原因,那个时候一切的新奇的,而且团队努力的过程也是一个平民向精英化过度的过程,t3一套给人感觉是神秘和羡慕,“人家是如何打本啊~~”正如此过程二就区分很,tbc后很都着急,着急穿上那些曾经代表荣誉的套装,着急穿上那些曾经区分所谓高玩和低玩的标志,着急穿上曾经无数人希望却可遇不可求的东西,本来blz设计思路是就全民体验fb化,由于没有困难模式,因此fb越来越简单,但是那些着急的人们不知道,当他们能轻松穿上以前身份装的时候,其实这个身份装的区别性早就消失了。当你没有使用new关键字调用函数时,此处只是一个函数表达式,表示对象的引用,该函数的属性其实是挂载在window对象下面的,由检测也可知,注意这是在非严格模式下的,严格模式则该this并不指向任何谁,返回一个undefined值,若添加属性是会报错的,对于普通函数调用前,若无new关键字,则它并没有实例化(创建)一个对象,该this值并不指向该创建的对象,若有new构造器函数的调用,在使用上与内置构造器上并无多大的区别,有new和无new函数的调用,是有很大的区别的,个人建议即使是在使用内置构造函数时,也不要省略该new关键字,并且构造函数的首字目大写,这一点沿袭了内置构造函数的特征,主要是为了区分与普通函数的区别,警示我们这是构造函数,实例出的对象,也就是创建了模板啊,具体构造函数细节在以后文章中详谈,下面是正确是使用new函数的调用,实现模板创建的过程,示例代码如下:
fopen函数以‘rb’模式 和 ‘r’ 模式打开文件的不同
年月 - 模式打开文件。 乱码是多余的垃圾值(初始化时赋的初始值)。ftell()返回值比fread()返回值大。fread返回实际得到的字符数,正常情况文本文件中\r\n读取后变成了\n,这就会导致读取
fread "rb"与"r","wb","w"的区别
年月 - 在fread时,"rb"与"r"对某些字符作用,是不同的;文本模式和二进制模式读取不一样的文本:读: 遇到回车-换行(0D 0A),就会转换为换行符0A 写:遇到
fread "rb"与"r","wb","w"的区别
这次我输入了zhang和回车换行,fgets函数依然是读取5个字符(len-1个),这时fgets()读入zhang,已经是五个字符了,所以回车换行并不会读入,最后fgets()添加字符串结束标志'\0',所以我们看到输出时,press any.并没有换行输出,而是和zhang在同一行。//从文件中读取字符到字符串str1,当遇到字符''a''或读取了个字符时终止。当以文本形式读取文件内容, 读入的字符值等于eof时, 表示读入的已不是正常的字符而是文件结束符。
fread读文件(rb方式fopen),怎样识别字符串中的换行符和回车符
为了知道自己写的php到底有没有被调用,在php写了一个简单的文件写入函数,我将当前的时间写入到一个test.txt中,只要查看test.txt, 我就知道php是有没有调用,什么时候调用,这样就可以大致看出来,自己设置的调用时间是不是被正确执行了。当按下选中键时,先判断是否已经选中了要移动的区域,如果已经选中了要移动的区域就调用move()函数完成由要移动的区域到要移动到的区域的移动过程,接着调用repaint()函数刷新屏幕,然后将已选择标记置成false,继续调用win()函数判断是否完成了任务,否则如果还没有选定要移动的区域则再判断当前选中区域是否为空白,如果不是空白就将选中标记置成true,然后刷新屏幕.这里介绍一个技巧,在开发程序遇到复杂的逻辑的时候,可以构造一格打印函数来将所关心的数据结构打印出来以利调试,这里我们就构造一个printgrid()函数,这个函数纯粹是为了调试之用,效果这得不错.至此我们完成了编码前的全部工作。当按下向下时,先判断是否已经选定了要移动的区域,如果没有选中要移动的区域则判断当前所处的区域是否为两个格高,如果是两个格高则向下移动两格,如果是一个格高则向下移动一格,接着再调用setrange()函数设置选择要移动的区域,而后调用repaint()函数刷新屏幕,否则如果已经选中了要移动的区域,就让光标向下移动一格,然后调用setmoverange()函数判断是否能够向下移动已选中的区域,如果能移动就调用repaint()函数刷新屏幕,如果不能移动就让光标向上退回到原来的位置.按下向左时情况完全类似向上的情况,按下向右时情况完全类似向下的情况,因此这里不再赘述,详细情况请参见程序的源代码。
使用fread读取二进制文件时,一定打开的时候使用‘rb’,不要只写r
调用了3次writefile,第一次写了个字节"hello world"(offset=0),第二次又写了同样的个字节,因为没有指定offset,所以把第一次写的给覆盖了,第三次使用一个overlapped结构指定offset,从offset=6开始写个字节"hello world"。助记符代码 说明mov a,rn e8~ef寄存器amov a,direct e5 direct 直接字节送amov a,@ri er~e7 间接ram送amov a,#data data立即数送amov rn,a f8~ff a送寄存器mov rn,direct a8~af direct 直接字节送寄存器mov rn,#data ~7f data立即数送寄存器mov direct,a f5 direct a送直接字节mov direct,rn ~8f direct 寄存器送直接字节mov direct1,direct2 direct1 direct2 直接字节送直接字节mov direct,@ro ~ 间接ram送直接字节mov direct,#data direct data立即数送直接字节mov @ri,a f6~f7 a送间接rammov @ri,direct ~ direct 直接字节送间接rammov @ri,#data ~ data 立即数送间接rammov dptr,#data data ~8 位常数送数据指针data7~0movc a,@a+dptr 由寻址的程序存贮器字节选amovc a,@a+pc 由)。stc单片机的内部eeprom是用dataflash模拟出来的,不是真正的eeprom存储器,不能用普通的方法来操作下面是一些注意点:1.字节写之前要先将这个字节所在扇区的其它有效数据读取到ram暂存(这步不是必须的)2.暂存完之后再对整个扇区(字节)进行擦除操作,擦拭完后,整个扇区每个地址中数据都变成0xff3.将欲写入的n个字节数据,用字节写函数写入eeprom4.
Linux系统命令中exit与exit的区别
注:exit()就是退出,传入的参数是程序退出时的状态码,0表示正常退出,其他表示非正常退出,一般都用-1或者1,标准C里有EXIT_SUCCESS和EXIT_FAILURE两个宏,用exit(EXIT_SUCCESS);可读性比较好一点。作为系统调用而言,_exit和exit是一对孪生兄弟,它们究竟相似到什么程度,我们可以从Linux的源码中找到答案:
#define __NR__exit __NR_exit /* 摘自文件include/asm-i/unistd.h第行 */
"__NR_"是在Linux的源码中为每个系统调用加上的前缀,请注意第一个exit前有2条下划线,第二个exit前只有1条下划线。 这时随便一个懂得C语言并且头脑清醒的人都会说,_exit和exit没有任何区别,但我们还要讲一下这两者之间的区别,这种区别主要体现在它们在函数库中的定义。_exit在Linux函数库中的原型是:
#i ncludeunistd.h void _exit(int status);
和exit比较一下,exit()函数定义在stdlib.h中,而_exit()定义在unistd.h中,从名字上看,stdlib.h似乎比 unistd.h高级一点,那么,它们之间到底有什么区别呢? _exit()函数的作用最为简单:直接使进程停止运行,清除其使用的内存空间,并销毁其在内核中的各种数据结构;exit() 函数则在这些基础上作了一些包装,在执行退出之前加了若干道工序,也是因为这个原因,有些人认为exit已经不能算是纯粹的系统调用。 exit()函数与_exit()函数最大的区别就在于exit()函数在调用exit系统调用之前要检查文件的打开情况,把文件缓冲区中的内容写回文件,就是"清理I/O缓冲"。
exit()在结束调用它的进程之前,要进行如下步骤:
1.调用atexit()注册的函数(出口函数);按ATEXIT注册时相反的顺序调用所有由它注册的函数,这使得我们可以指定在程序终止时执行自己的清理动作.例如,保存程序状态信息于某个文件,解开对共享数据库上的锁等.
2.cleanup();关闭所有打开的流,这将导致写所有被缓冲的输出,删除用TMPFILE函数建立的所有临时文件.
3.最后调用_exit()函数终止进程。
_exit做3件事(man): 1,Any open file descriptors belonging to the process are closed 2,any children of the process are inherited by process 1, init 3,the process‘s parent is sent a SIGCHLD signal
exit执行完清理工作后就调用_exit来终止进程。
此外,另外一种解释:
简单的说,exit函数将终止调用进程。在退出程序之前,所有文件关闭,缓冲输出内容将刷新定义,并调用所有已刷新的“出口函数”(由atexit定义)。
_exit:该函数是由Posix定义的,不会运行exit handler和signal handler,在UNIX系统中不会flush标准I/O流。
简单的说,_exit终止调用进程,但不关闭文件,不清除输出缓存,也不调用出口函数。
共同:
不管进程是如何终止的,内核都会关闭进程打开的所有file descriptors,释放进程使用的memory!
更详细的介绍:
Calling exit() The exit() function causes normal program termination.
The exit() function performs the following functions:
1. All functions registered by the Standard C atexit() function are called in the reverse order of registration. If any of these functions calls exit(), the results are not portable. 2. All open output streams are flushed (data written out) and the streams are closed.
3. All files created by tmpfile() are deleted.
4. The _exit() function is called. Calling _exit() The _exit() function performs operating system-specific program termination functions. These include: 1. All open file descriptors and directory streams are closed.
2. If the parent process is executing a wait() or waitpid(), the parent wakes up and status is made available.
3. If the parent is not executing a wait() or waitpid(), the status is saved for return to the parent on a subsequent wait() or waitpid(). 4. Children of the terminated process are assigned a new parent process ID. Note: the termination of a parent does not directly terminate its children. 5. If the implementation supports the SIGCHLD signal, a SIGCHLD is sent to the parent. 6. Several job control signals are sent.
为何在一个fork的子进程分支中使用_exit函数而不使用exit函数? ‘exit()’与‘_exit()’有不少区别在使用‘fork()’,特别是‘vfork()’时变得很 突出。
‘exit()’与‘_exit()’的基本区别在于前一个调用实施与调用库里用户状态结构(user-mode constructs)有关的清除工作(clean-up),而且调用用户自定义的清除程序 (自定义清除程序由atexit函数定义,可定义多次,并以倒序执行),相对应,_exit函数只为进程实施内核清除工作。 在由‘fork()’创建的子进程分支里,正常情况下使用‘exit()’是不正确的,这是 因为使用它会导致标准输入输出(stdio: Standard Input Output)的缓冲区被清空两次,而且临时文件被出乎意料的删除(临时文件由tmpfile函数创建在系统临时目录下,文件名由系统随机生成)。在C++程序中情况会更糟,因为静态目标(static objects)的析构函数(destructors)可以被错误地执行。(还有一些特殊情况,比如守护程序,它们的父进程需要调用‘_exit()’而不是子进程;适用于绝大多数情况的基本规则是,‘exit()’在每一次进入‘main’函数后只调用一次。) 在由‘vfork()’创建的子进程分支里,‘exit()’的使用将更加危险,因为它将影响父进程的状态。
#include sys/types.h; #include stdio.h int glob = 6; /* external variable in initialized data */ int main(void) { int var; /* automatic variable on the stack */ pid_t pid; var = ; printf("before vfork/n"; /* we don‘t flush stdio */ if ( (pid = vfork()) 0) printf("vfork error/n"; else if (pid == 0) { /* child */ glob++; /* modify parent‘s variables */ var++; exit(0); /* child terminates */ //子进程中最好还是用_exit(0)比较安全。 } /* parent */ printf("pid = %d, glob = %d, var = %d/n", getpid(), glob, var); exit(0); } 在Linux系统上运行,父进程printf的内容输出:pid = , glob = 7, var =
子进程 关闭的是自己的, 虽然他们共享标准输入、标准输出、标准出错等 “打开的文件”, 子进程exit时,也不过是递减一个引用计数,不可能关闭父进程的,所以父进程还是有输出的。
但在其它UNIX系统上,父进程可能没有输出,原 因是子进程调用了e x i t,它刷新关闭了所有标准I / O流,这包括标准输出。虽然这是由子进程执行的,但却是在父进程的地址空间中进行的,所以所有受到影响的标准I/O FILE对象都是在父进程中的。当父进程调用p r i n t f时,标准输出已被关闭了,于是p r i n t f返回- 1。
在Linux的标准函数库中,有一套称作"高级I/O"的函数,我们熟知的printf()、fopen()、fread()、fwrite()都在此 列,它们也被称作"缓冲I/O(buffered I/O)",其特征是对应每一个打开的文件,在内存中都有一片缓冲区,每次读文件时,会多读出若干条记录,这样下次读文件时就可以直接从内存的缓冲区中读取,每次写文件的时候,也仅仅是写入内存中的缓冲区,等满足了一定的条件(达到一定数量,或遇到特定字符,如换行符和文件结束符EOF), 再将缓冲区中的 内容一次性写入文件,这样就大大增加了文件读写的速度,但也为我们编程带来了一点点麻烦。如果有一些数据,我们认为已经写入了文件,实际上因为没有满足特 定的条件,它们还只是保存在缓冲区内,这时我们用_exit()函数直接将进程关闭,缓冲区中的数据就会丢失,反之,如果想保证数据的完整性,就一定要使用exit()函数。
Exit的函数声明在stdlib.h头文件中。
_exit的函数声明在unistd.h头文件当中。
下面的实例比较了这两个函数的区别。printf函数就是使用缓冲I/O的方式,该函数在遇到“/n”换行符时自动的从缓冲区中将记录读出。实例就是利用这个性质进行比较的。
exit.c源码
#include stdlib.h #include stdio.h int main(void) { printf("Using exit.../n"); printf("This is the content in buffer"); exit(0); }
输出信息:
Using exit...
This is the content in buffer
#include unistd.h #include stdio.h int main(void) { printf("Using exit.../n"); //如果此处不加“/n”的话,这条信息有可能也不会显示在终端上。 printf("This is the content in buffer"); _exit(0); }
则只输出:
Using exit...
说明:在一个进程调用了exit之后,该进程并不会马上完全消失,而是留下一个称为僵尸进程(Zombie)的数据结构。僵尸进程是一种非常特殊的进程,它几乎已经放弃了所有的内存空间,没有任何可执行代码,也不能被调度,仅仅在进程列表中保留一个位置,记载该进程的退出状态等信息供其它进程收集,除此之外,僵尸进程不再占有任何内存空间。
#include stdio.h;
int main() { printf("%c", ‘c‘); _exit(0); }
怎么把文本文件的内容作为可执行文件的输入数据
如果你是直接调用.exe,那么是没有办法的。除非你在另外一个程序(假如:A)内调用.exe,可以在A内把text.txt的内容读出来,再作为.exe的参数。
从main(int argc, char** argv)函数入口你可以看出,任何跟在.exe后的内容都作为参数处理了。因此,一般的处理方法是,把text.txt作为.exe的参数,然后在.exe程序main函数开始,把text.txt的内容读取出来,根据你的需要做进一步处理。结果和你的期望是一样的。