socket程式設計(五)

2021-08-02 19:21:28 字數 4298 閱讀 2719

(1)recv只能接收套接字io

(2)recv有flags選項

(3)recv選項:msg_oob接收帶外資料,通過緊急指標,tcp選項

(4)recv選項:msg_peek接收緩衝區中的資料,但是不將緩衝區中的資料清除

//從套介面接收資料,但是不從緩衝區中移除msg_peek

//只要有偷看到資料就接收,沒有頭看到就是阻塞

//對方套介面關閉,返回0

ssize_t recv_peek(int sockfd, void* buf, size_t len)

}//讀取遇到\r\n截止,最大不能超過maxline

ssize_t readline(int sockfd, void* buf, size_t maxline)

return -1;

}

echoserver.cpp

#include #include #include #include #include #include #include #include #include #define err_exit(m) \

do \

while(0)

/* param1:fd, param2:buf, param3:count

return:讀取成功位元組數

ssize_t:有符號

size_t:無符號

*/ssize_t readn(int fd, void* buf, size_t count) else if (0 == nread)

bufp += nread;

nleft -= nread;

}return count;}/*

param1:fd, param2:buf, param3:count

return:已經傳送了多少

*/ssize_t writen(int fd, void* buf, size_t count) else if(0 == nwrite)

bufp += nwrite;

nleft -= nwrite;

} return count;

}//從套介面接收資料,但是不從緩衝區中移除msg_peek

//只要有偷看到資料就接收,沒有頭看到就是阻塞

//對方套介面關閉,返回0

ssize_t recv_peek(int sockfd, void* buf, size_t len)

}//讀取遇到\r\n截止,最大不能超過maxline

ssize_t readline(int sockfd, void* buf, size_t maxline)

return -1;

}void do_service(int conn) else if(0 == ret)

fputs(recvbuf, stdout);

writen(conn, recvbuf, strlen(recvbuf));

}}int main ()

if(pid == 0) else

}close(listenfd);

close(conn);

return 0;

}

echoclient.cpp

#include #include #include #include #include #include #include #include #include #define err_exit(m) \

do \

while(0)

ssize_t readn(int fd, void* buf, size_t count) else if (0 == nread)

bufp += nread;

nleft -= nread;

}return count;

}ssize_t writen(int fd, void* buf, size_t count) else if(0 == nwrite)

bufp += nwrite;

nleft -= nwrite;

} return count;

}ssize_t recv_peek(int sockfd, void* buf, size_t len)

}//讀取遇到\r\n截止,最大不能超過maxline

ssize_t readline(int sockfd, void* buf, size_t maxline)

return -1;

}int main () ;

char recvbuf[1024] = ;

int n;

while(fgets(sendbuf, sizeof(sendbuf), stdin) != null) else if(0 == ret)

fputs(recvbuf, stdout);

memset(sendbuf, 0, sizeof(sendbuf));

memset(recvbuf, 0, sizeof(recvbuf));

}close(sock);

return 0;

}

(1)getsockname獲得本端ip和port

(2)getpeername得到對端addr,port[套接字socket必須是已連線的套接字]

//獲得本端ip,port

struct sockaddr_in localaddr;

socklen_t addrlen= sizeof(localaddr);

if(getsockname(sock,(struct sockaddr*)&localaddr, &addrlen) < 0)

err_exit("getsockname");

printf("ip=%s port=%d\n", inet_ntoa(localaddr.sin_addr), ntohs(localaddr.sin_port));

struct sockaddr_in connaddr;

socklen_t connlen = sizeof(connaddr);

//通過getpeername得到對端addr,port[conn必須是已連線的套接字]

getpeername(sock, (struct sockaddr*)&connaddr, &connlen);

printf("ip=%s port=%d\n", inet_ntoa(connaddr.sin_addr), ntohs(connaddr.sin_port));

(1)gethostname獲得主機名

(2)gethostbyname通過主機名獲得ip

#include #include #include #include #include #include #include #include #include #include #define err_exit(m) \

do \

while(0)

//獲得本地ip位址

int getlocalip(char* ip) ;

if(gethostname(host, sizeof(host)) < 0)

return -1;

struct hostent* hp;

if((hp = gethostbyname(host)) == null)

return -1;

//strcpy(ip, inet_ntoa(*(struct in_addr*)hp->h_addr_list[0]));

strcpy(ip, inet_ntoa(*(struct in_addr*)hp->h_addr));

return 0;

}int main(void) ;

if(gethostname(host, sizeof(host)) < 0)

err_exit("gethostname");

printf("%s\n", host);

//通過主機名得到ip位址

struct hostent* hp;

if((hp = gethostbyname(host)) == null)

err_exit("gethostbyname");

int i =0;

while(hp->h_addr_list[i] != null)

char ip[16] = ;

getlocalip(ip);

printf("localip=%s\n", ip);

return 0;

}

五 socket實踐程式設計

1 伺服器端程式編寫 1 socket 2 bind 3 listen 4 accept,返回值是乙個fd,accept正確返回就表示我們已經和前來連線我的客戶端之間建立了乙個tcp連線了,以後我們就要通過這個連線來和客戶端進行讀寫操作,讀寫操作就需要乙個fd,這個fd就由accept來返回了。注意...

Linux下Socket程式設計學習(五)

這章講下產生sigpipe訊號的原因 往乙個已經收到fin的套接字中寫是允許的,接收到fin僅僅代表對方不再傳送資料。如果對方程序不存在了,你還寫資料那麼會返回乙個rst段rst段之後,如果再呼叫write就會產生sigpipe訊號,對於這個訊號直接忽略就ok了 singal sigpipe,sig...

socket程式設計

一直以為serversocket accept之後客戶端才能發資訊,實驗後得出如下結論 1 serversocket沒有accept時,client是可以傳送資訊到server端的。2 serversocket accept之後,正在處理訊息時,client也是可以傳送資訊到server端。如果se...