服務器代碼:
#include<sys/socket.h>
#include<netinet/in.h>
#include<sys/types.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
int main()
{
int res,listenfd,clientfd; //返回值,監聽套接字,客戶套接字
char buff[BUFSIZ]="";
int len;
struct sockaddr_in serveraddr; //地址類型
bzero(&serveraddr,sizeof(serveraddr)); //清空
serveraddr.sin_family=AF_INET; //使用AF_INET域
serveraddr.sin_addr.s_addr=htonl(INADDR_ANY); //可以連接到本服務器的地址類型,即IP類型,這裡是任意類型
serveraddr.sin_port=htons(50002);//指定端口號
len=sizeof(serveraddr);
listenfd=socket(AF_INET,SOCK_STREAM,0); //創建套接字
bind(listenfd,(struct sockaddr*)&serveraddr,len);//命名套接字
listen(listenfd,23); //設置可連接的數量
clientfd=accept(listenfd,NULL,NULL); //接受鏈接
printf("connecct a client\n");
while(strncmp(buff,"end",3))
{
res=read(clientfd,buff,BUFSIZ); //從客戶端讀取數據
write(2,buff,res); //把數據顯示到顯示器,最好用write來顯示,如果用printf燈可能顯示上次留下的數據
write(clientfd,"server",6); //往客戶端寫數據
}
close(clientfd);//關閉客戶端
close(listenfd); //關閉監聽
exit(0);
}
客戶端代碼:
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(int argc,char *argv[])
{
int res,connfd,len; //返回值,連接套接字,地址長度
struct sockaddr_in connaddr; //客戶端要鏈接的服務器的地址,應該與服務器的地址一致
char buff[BUFSIZ];
bzero(&connaddr,sizeof(connaddr)); //清空套接字
if(argc<2)
{
printf("the option is too less\n");
exit(0);
}
connaddr.sin_family=AF_INET; //使用AF_INET域
connaddr.sin_addr.s_addr=inet_addr(argv[1]);//確定要鏈接的地址
connaddr.sin_port=htons(50002);//要鏈接的端口號
connfd=socket(AF_INET,SOCK_STREAM,0);//創建套接字
len=sizeof(connaddr);//獲取地址長度
connect(connfd,(struct sockaddr*)&connaddr,len);//創建鏈接
write(connfd,"Hello !",7);//往服務器寫數據
while(res=read(connfd,buff,BUFSIZ))
{
printf("%d\n",res); //顯示收到的字節數
res=read(fileno(stdin),buff,BUFSIZ); //從服務器讀取數據
write(connfd,buff,res);
}
close(connfd);//關閉套接字
exit(0);
}
雖然每次服務器,客戶端都會給對方發送一個ACK來確認收到,但read函數一般不會讀取到,如果某一方發送FIN或RST信號,read都會當作讀到文件尾來處理,即返回0;