導航:首頁 > 編程系統 > linuxwnohang

linuxwnohang

發布時間:2023-06-09 07:42:55

A. linux下的 socket編程問題!

第一個問題:

對,是那樣的,用open打開文件,用read讀取文件,在發送給對方,接收方接收到後,寫入文件就可以了。不過在這個過程中最好別用字元串函數,除非你很熟悉。

第二個問題

首先你得去搞清楚什麼是線程,什麼是進程,fork出來的叫進程,pthread_create出來的才叫線程。伺服器有很多種模型(多進程,多線程,select,epoll模型,這個我的blog上有,famdestiny.cublog.cn),不一定要用多進程。

給你寫了個代碼,自己先看看:

注意,在自己的目錄下創建一個叫pserverb的文件,程序會把這個文件復製成test文件。你可以自己根據需要改改

server:

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#define SERV_PORT 5358
#define MAX_CONN 10
#define BUF_LEN 1024

void str_echo(FILE *fp, int sockfd){
ssize_t nread;
int file_fd;
char buf[BUF_LEN] = {0};

file_fd = open("test", O_WRONLY | O_TRUNC | O_CREAT, 0755);
while(1) {
bzero(buf, BUF_LEN);
if((nread = read(sockfd, buf, BUF_LEN)) == -1) {
if(errno == EINTR) {
continue;
}
else {
printf("readn error: %s\n", strerror(errno));
continue;
}
}
else if (nread == 0) {
break;
}
else {
printf("%s\n", buf);
write(file_fd, buf, nread);
}
}
close(file_fd);
}

void sig_chld(int sig){
pid_t pid;
int state;
while((pid = waitpid(-1, &state, WNOHANG)) > 0){
printf("child process %d exited.", pid);
}
return;
}

int main(int argc, char **argv)
{
int listenfd, connfd;
socklen_t cliaddrlen;
pid_t childpid;
struct sockaddr_in servaddr, cliaddr;

if((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
printf("socket error: %s\n", strerror(errno));
return 0;
}

bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
if(bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1){
printf("bind error: %s\n", strerror(errno));
return 0;
}

if(listen(listenfd, MAX_CONN) == -1){
printf("listen error: %s\n", strerror(errno));
return 0;
}

signal(SIGCHLD, sig_chld);

while(1){
cliaddrlen = sizeof(cliaddr);
if((connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddrlen)) == -1){
if(errno == EINTR){
continue;
}
else{
printf("accept error: %s\n", strerror(errno));
continue;
}
}

if((childpid = fork()) == 0){
close(listenfd);
str_echo(stdin, connfd);
exit(0);
}
else if(childpid > 0){
close(connfd);
}
else{
printf("fork error!\n");
continue;
}
}
}

client:

#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>

#define SERV_ADDR "127.0.0.1"
#define SERV_PORT 5358
#define BUF_LEN 1024

void str_cli(char *path, int sockfd)
{
char sendbuf[BUF_LEN] = {0};
int fd, n;

if((fd = open("./pserverb", O_RDONLY)) == -1){
printf("%s\n", strerror(errno));
exit(0);
}
while((n = read(fd, sendbuf, BUF_LEN)) != 0) {
if(n < 0){
printf("%s\n", strerror(errno));
exit(0);
}
write(sockfd, sendbuf, n);
bzero(sendbuf, BUF_LEN);
}
close(fd);
return;
}

int main(int argc, char **argv)
{
int fd;
struct sockaddr_in servaddr;

fd = socket(AF_INET, SOCK_STREAM, 0);

bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr(SERV_ADDR);
servaddr.sin_port = htons(SERV_PORT);

if (connect(fd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) {
printf("connect error: %s\n", strerror(errno));
return 0;
}

str_cli(argv[1], fd);
return 0;
}

B. 如何在linux中編寫一個類似CreateProcess的函數

CreateProcess函數可以創建一個新的進程並調用一個外部程序

並且它有很多參數可以設置新的進程相關的狀態

如果只要想簡單地完成創建一個進程並調用一個外部程序的話

在linux上可以使用fork或者clone來進行創建進程

然後使用exec族函數來調用一個外部程序

一個簡單的實現大概是這樣的

intcreate_procress(constchar*path,constchar*name,constchar*arg)
{
pid_tpid;

pid=fork();
if(pid==0)
{
if(execl(path,name,arg,NULL)==-1)
{
perror(path);
_exit(-1);
}
}
elseif(pid==-1)
return-1;

return0;
}

參數path為執行外部程序的路徑

name為運行程序的名稱(argv[0])

arg為命令行參數(從argv[1]開始)


如果對新進程有其它需求的話比如設置環境變數等可以使用execle等進行擴展

或者其它的要求也可以使用linux提供的相應api在fork後進行設置

C. 下面是我在linux下寫的守護進程,現在想收到SIGUSR1的信號後跳出while循環,該怎麼寫

守護進程只知道抄過程,沒具體實現過,但我想了想,你可以設置一個變數,給變數一個初值比如count = 1;然後while(count),然後你收到SIGUSR1後去執行特定函數,把count置零,這樣就可以實現。 然後再一個if語句,判count是否為0,為0就break,這樣就達到目的了,俺不是牛人,就想到了這個辦法,有好辦法分享一下哈。。。

D. 如何在Linux下實現client和server的互傳

就是一個TCP通信的過程嘛,可以參考如下程序源碼,望採納!另外,可以找一些linux網路編程的資料看看。
/* tcpcli.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define DEFAULT_PORT 8800
int main(int argc, char** argv)
{
int cPort = DEFAULT_PORT;
int cClient = 0;
int cLen = 0;
struct sockaddr_in cli;
char cbuf[4096] = {0};

if(argc < 2)
{
printf("Uasge: client[server IP address]\n");
return -1;
}

memset(cbuf, 0, sizeof(cbuf));

cli.sin_family = AF_INET;
cli.sin_port = htons(cPort);
cli.sin_addr.s_addr = inet_addr(argv[1]);

cClient = socket(AF_INET, SOCK_STREAM, 0);
if(cClient < 0)
{
printf("socket() failure!\n");
return -1;
}

if(connect(cClient, (struct sockaddr*)&cli, sizeof(cli)) < 0)
{
printf("connect() failure!\n");
return -1;
}

cLen = recv(cClient, cbuf, sizeof(cbuf),0);
if((cLen < 0)||(cLen == 0))
{
printf("recv() failure!\n");
return -1;
}
printf("recv() Data From Server: [%s]\n", cbuf);

close(cClient);

return 0;
}
編譯代碼:gcc -o tcp_clt client_tcp.c
執行命令:./tcp_clt 192.168.0.230
TCP scoket服務端程序代碼
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include<sys/wait.h>
#include <string.h>
/*********************************************************************
*filename: tcpserver.c
*purpose:tcp服務端程序
********************************************************************/
int main(int argc, char ** argv)
{
int sockfd,new_fd; /* 監聽socket: sock_fd,數據傳輸socket: new_fd */
struct sockaddr_in my_addr; /* 本機地址信息 */
struct sockaddr_in their_addr; /* 客戶地址信息 */
unsigned int sin_size, myport, lisnum;

if(argv[1]) myport = atoi(argv[1]);
else myport = 8800;

if(argv[2]) lisnum = atoi(argv[2]);
else lisnum = 2;

if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
printf("socket %d ok \n",myport);
my_addr.sin_family=PF_INET;
my_addr.sin_port=htons(myport);
my_addr.sin_addr.s_addr = INADDR_ANY;
bzero(&(my_addr.sin_zero), 0);
if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) {
perror("bind");
exit(1);
}
printf("bind ok \n");

if (listen(sockfd, lisnum) == -1) {
perror("listen");
exit(1);
}
printf("listen ok \n");

/*
while(1) {
sin_size = sizeof(struct sockaddr_in);
if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1) {
perror("accept");
continue;
}
printf("server: got connection from %s\n",inet_ntoa(their_addr.sin_addr));
if (!fork()) { //子進程代碼段
if (send(new_fd, "Hello, world!\n", 14, 0) == -1) {
perror("send");
close(new_fd);
exit(0);
}
}
close(new_fd); //父進程不再需要該socket
waitpid(-1,NULL,WNOHANG);//等待子進程結束,清除子進程所佔用資源
}
*/
sin_size = sizeof(struct sockaddr_in);
if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1) {
perror("accept");
exit(0);
}
printf("server: got connection from %s\n",inet_ntoa(their_addr.sin_addr));
int step = 0;
while(1) {
char szSnd[63] = {0};
sprintf(szSnd,"i am server [%d]\n",step);
step++;
if (send(new_fd, szSnd, strlen(szSnd), 0) == -1) {
perror("send");
close(new_fd);
break;
}
printf("send msg: %s \n",szSnd);
sleep(1);
}
exit(0);
}
}
編譯指令:gcc -o tcp_srv tcpserver.c
執行伺服器端程序:./tcp_srv
創建成功,綁定埠成功,監聽成功後,循環發送i am server字元串。

E. linux裡面的wait和waitpid是什麼

wait和waitpid的不同在於wait會令調用者阻塞直至某個子進程終止而waitpid則可以通過設置一個選項來設置為非阻塞,另外waitpid並不是等待第一個結束的進程而是等待參數中pid指定的進程。
waitpid提供了wait所沒有的三個特性:
1 waitpid使我們可以等待指定的進程
2 waitpid提供了一個無阻塞的wait
3 waitpid支持工作控制
具體可以查看APUE page202

F. linux下C語言socket編程雙機互發數據

這個問題很好辦啦,伺服器接受一個連接請求,然後開一個線程或者進程都可以,再在線程或者進程裡面採用其他技術實現同時收發(比如I/O復用,比如非阻塞I/O)。客戶端也可以採用I/O復用。

推薦資料的話,《unix網路編程》這本書很好,公認的經典,當教科書用,這本書里有你想要的所有內容。

ps:你基礎太差,多補補吧,別想一下吃個胖子。

另外我這里正好有個例子滿足你的要求,貼給你,自己寫的,不是網上找的,用的是多進程加I/O復用技術:

server端:
/****************************************************************
**
**
**
****************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/select.h>
#include <sys/time.h>
#include <unistd.h>

#define BUFLEN 1024
#define MAX(a,b) ((a)>(b)?(a):(b))

typedef void Sigfunc (int);

void str_echo(FILE *,int);
//Sigfunc *signal(int, Sigfunc *);

int main(int argc,char **argv)
{
int connfd,listenfd;
pid_t childpid;
socklen_t clilen;
struct sockaddr_in cliaddr,servaddr;
void sig_chld(int);

listenfd = socket(AF_INET, SOCK_STREAM, 0);

memset(&servaddr,0,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(5358);

bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr));
listen(listenfd,8);

signal(SIGCHLD,sig_chld);

while(1)
{
clilen = sizeof(cliaddr);
if((connfd = accept(listenfd,(struct sockaddr*)&cliaddr,&clilen)) < 0)
{
if(errno == EINTR)
{
fputs("accept error: EINTR\n",stdout);
continue;
}
else
{
fputs("accept error..\n",stdout);
}
}

if((childpid = fork()) == 0)
{
close(listenfd);
str_echo(stdin,connfd);
exit(0);
}
close(connfd);
}
}

void str_echo(FILE *fp,int sockfd)
{
int n = 0;
char sendbuf[BUFLEN] = { 0 },recvbuf[BUFLEN] = { 0 };
int maxfdp;
fd_set rset;

FD_ZERO(&rset);

while(1)
{
FD_SET(fileno(fp),&rset);
FD_SET(sockfd, &rset);
maxfdp = MAX(fileno(fp),sockfd)+1;

select(maxfdp, &rset ,NULL, NULL, NULL);

if(FD_ISSET(sockfd, &rset))
{
if(n = read(sockfd, recvbuf, BUFLEN) == 0)
{
return;
}
if(n == -1)
{
break;
}
printf("%s\n",recvbuf);
memset(recvbuf,0,BUFLEN);
}
if(FD_ISSET(fileno(fp),&rset))
{
scanf("%s",sendbuf);
write(sockfd, sendbuf,strlen(sendbuf));
}
}
}

void sig_chld (int signo)
{
pid_t pid;
int stat;

while ((pid = waitpid(-1,&stat, WNOHANG)) > 0)
{
printf("child %d terminated\n",pid);
}
return;
}

client端:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>

#define MAX(a,b) (a)>(b)?(a):(b)

int main()
{
int s,connectReturn, maxfd;
fd_set rset;
char sendbuf[1024] = {0};
char recvbuf[1024] = {0};
long port=5358;
s=socket(PF_INET,SOCK_STREAM,0);

struct sockaddr_in sa;
sa.sin_family=AF_INET;
sa.sin_addr.s_addr=inet_addr("127.0.0.1");
sa.sin_port=htons(port);
connectReturn=connect(s,(struct sockaddr *)&sa,sizeof(sa));
printf("%d\n",connectReturn);
FD_ZERO(&rset);
while(1)
{
FD_SET(fileno(stdin), &rset);
FD_SET(s, &rset);
maxfd=MAX(fileno(stdin), s) + 1;

select(maxfd, &rset, NULL, NULL, NULL);
if(FD_ISSET(fileno(stdin), &rset))
{
scanf("%s",sendbuf);
send(s,sendbuf,strlen(sendbuf),0);
bzero(sendbuf, 1024);
}
else if(FD_ISSET(s, &rset))
{
memset(recvbuf,0,1024);
recv(s,recvbuf,1024,0);
printf("remote: %s\n",recvbuf);
}
}
return 0;
}

G. linux下system函數調用shell命令後,怎樣讓主進程等子進程返回後,接著執行

這是進程間同步的問題。解決方法是:fork一個子進程執行system調用,父進程調用 wait 或 waitpid 等待子進程的終止信息。

父進程調用 wait 或 waitpid 時可能會:
• 阻塞(如果它的所有子進程都還在運行)。
• 帶子進程的終止信息立即返回(如果一個子進程已終止,正等待父進程讀取其終止信息)。
• 出錯立即返回(如果它沒有任何子進程)。

wait 和 waitpid 這兩個函數的區別是:
• 如果父進程的所有子進程都還在運行,調用wait將使父進程阻塞,而調用waitpid時如果在options參數中指定WNOHANG可以使父進程不阻塞而立即返回0。
• wait等待第一個終止的子進程,而waitpid可以通過pid參數指定等待哪一個子進程。

閱讀全文

與linuxwnohang相關的資料

熱點內容
java後台校驗框架 瀏覽:379
編程怎麼做3d生存游戲 瀏覽:955
word使用教程下載 瀏覽:295
電腦文件平鋪圖片默認大小 瀏覽:115
文件查看設置信息失敗 瀏覽:668
編程如何編出烏鴉喝水的課文 瀏覽:20
國家反詐app報案助手怎麼使用 瀏覽:439
秘密文件丟失多少天 瀏覽:237
js中csstext 瀏覽:382
目標文件名過長復制 瀏覽:892
樂動力計步器老版本 瀏覽:933
壓縮文件鏈接怎麼編輯 瀏覽:808
如何鎖定PDF文件里的圖章 瀏覽:89
資料庫超時是什麼 瀏覽:649
文件怎麼改整列內容 瀏覽:764
360壓縮文件發郵件空白 瀏覽:813
上哪裡查自己大數據 瀏覽:907
編程語言怎麼學車 瀏覽:189
編程該怎麼學才能先找工作 瀏覽:524
文件刻制光碟多少錢 瀏覽:861

友情鏈接