(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...