#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<stdio.h>
#include<string.h>
#include<unistd.h>
//server端
int main()
{
int ret = 0;
int sfd = socket(PF_INET,SOCK_STREAM,0);
if(sfd < 0)
{
perror("socket");
return -1;
}
struct sockaddr_in si;
si.sin_family = PF_INET;
si.sin_port = htons(50000);
inet_pton(PF_INET,"192.168.22.50",&si.sin_addr);
ret = bind(sfd,(struct sockaddr*)&si,sizeof si);
if(ret < 0)
{
perror("bind");
return ret;
}
ret = listen(sfd,10);
if(ret < 0)
{
perror("listen");
return ret;
}
for(;;)
{
struct sockaddr_in ss;
socklen_t len = sizeof ss;
int afd = accept(sfd,(struct sockaddr*)&ss,&len);
if(afd < 0)
{
perror("accept");
return -1;
}
char buf[100] = "hello furong ";
ret = send(afd,buf,strlen(buf),0);
sleep(1);
}
}
注:
如果socket客户端没有接收函数,此时send发送,会导致服务器崩溃
//client端
int main()
{
int sfd = socket(PF_INET,SOCK_STREAM,0);
if(sfd < 0)
{
perror("socket");
return -1;
}
struct sockaddr_in si;
si.sin_family = PF_INET;
si.sin_port = htons(50000);
inet_pton(PF_INET,"192.168.22.50",&si.sin_addr);
int res = connect(sfd,(struct sockaddr*)&si,sizeof si);
if(res < 0)
{
perror("connect");
return res;
}
for(;;)
{
char buf[100] = {0};
//memset();
res = recv(sfd,buf,sizeof(buf),0);
}
}
清空缓冲区:
scanf("%*[^\n]");
获取客户端IP、PORT
struct sockaddr_in ss;
socklen_t len = sizeof ss;
accept(sfd,(struct sockaddr*)&ss,&len);
inet_ntoa(ss.sin_addr);
ntohs(ss.sin_port);
recv函数最后一个参数
MSG_DONTWAIT 函数不阻塞
解决端口占用:
int reuseaddr = 1;
setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&reuseaddr,sizeof(reuseaddr));
关闭nagle算法(网络较慢,发生粘包):
socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
const int bNodelay = 1;
setsockopt(sockfd ,IPPROTO_TCP,TCP_NODELAY,(char *)&bNodelay,sizeof(bNodelay));
通过查看netinet/tcp.h和linux/tcp.h,得到TCP_NODELAY的定义
recv操作有多种错误码
#include <errno.h>
printf("%d\n",errno);
perror("func");
recv错误码位于“/usr/include/linux/nfs.h”