关键函数
1、int socket(int family,int type,int protocol)
family:指定使用的协议簇:AF_INET(IPv4) AF_INET6(IPv6) AF_LOCAL(UNIX协议) AF_ROUTE(路由套接字) AF_KEY(秘钥套接字)
type:指定使用的套接字的类型:SOCK_STREAM(字节流套接字) SOCK_DGRAM
protocol:如果套接字类型不是原始套接字,那么这个参数就为0
return:如果返回值>0 ,标示 Socket 创建成功!
2、int bind(int sockfd, struct sockaddr *myaddr, int addrlen)
sockfd:socket函数返回的套接字描述符
myaddr:是指向本地IP地址的结构体指针
myaddrlen:结构长度
struct sockaddr{unsigned short sa_family; char sa_data[14];
};
struct sockaddr_in{short int sin_family; unsigned short int sin_port; struct in_addr sin_addr; unsigned char si_zero[8];
};
3、int connect(int sockfd,const struct sockaddr *serv_addr,socklen_t addrlen)
sockfd:socket函数返回套接字描述符
serv_addr:服务器IP地址结构指针
addrlen:结构体指针的长度
return:成功返回0,失败返回-1
4、int listen(int sockfd, int backlog)
sockfd:socket函数绑定bind后套接字描述符
backlog:设置可连接客户端的最大连接个数,当有多个客户端向服务器请求时,收到此值的影响。默认值20
5、int accept(int sockfd,struct sockaddr *cliaddr,socklen_t *addrlen)
sockfd:socket函数经过listen后套接字描述符
cliaddr:客户端套接字接口地址结构
addrlen:客户端地址结构长度
6、int send(int sockfd, const void *msg,int len,int flags)
7、int recv(int sockfd, void *buf,int len,unsigned int flags)
sockfd:socket函数的套接字描述符
msg:发送数据的指针
buf:存放接收数据的缓冲区
len:数据的长度,把flags设置为0
return:>0表示成功&#xff0c;返回实际发送或接受的字节数;&#61;0表示超时&#xff0c;对方主动关闭了连接过程;<0出错&#xff0c;此种情况可能出现过重情况,其中errno &#61;&#61; EINTR || errno &#61;&#61; EWOULDBLOCK || errno &#61;&#61; EAGAIN这三种是特殊情况&#xff0c;实际使用中表示继续正常接受数据即可。
服务端
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include int main(int argc, char *argv[])
{int fd, new_fd, struct_len, numbytes,i;struct sockaddr_in server_addr;struct sockaddr_in client_addr;char buff[BUFSIZ];server_addr.sin_family &#61; AF_INET;server_addr.sin_port &#61; htons(8000);server_addr.sin_addr.s_addr &#61; INADDR_ANY;bzero(&(server_addr.sin_zero), 8);struct_len &#61; sizeof(struct sockaddr_in);fd &#61; socket(AF_INET, SOCK_STREAM, 0);while(bind(fd, (struct sockaddr *)&server_addr, struct_len) &#61;&#61; -1);printf("Bind Success!\n");while(listen(fd, 10) &#61;&#61; -1);printf("Listening....\n");printf("Ready for Accept,Waitting...\n");new_fd &#61; accept(fd, (struct sockaddr *)&client_addr, &struct_len);printf("accept return: %d\n", new_fd);printf("Get the Client~\n");numbytes &#61; send(new_fd,"Welcome to my server\n",21,0);while((numbytes &#61; recv(new_fd, buff, BUFSIZ, 0)) > 0){buff[numbytes] &#61; &#39;\0&#39;;printf("%s\n",buff);if(send(new_fd,buff,numbytes,0)<0){perror("write");return 1;}}close(new_fd);close(fd);return 0;
}
客户端
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include int main(int argc,char *argv[])
{int sockfd,numbytes;char buf[BUFSIZ];struct sockaddr_in their_addr;printf("break!");while((sockfd &#61; socket(AF_INET,SOCK_STREAM,0)) &#61;&#61; -1);printf("We get the sockfd~\n");their_addr.sin_family &#61; AF_INET;their_addr.sin_port &#61; htons(8000);their_addr.sin_addr.s_addr&#61;inet_addr("127.0.0.1");bzero(&(their_addr.sin_zero), 8);while(connect(sockfd,(struct sockaddr*)&their_addr,sizeof(struct sockaddr)) &#61;&#61; -1);printf("connect return: %d\n", connect(sockfd,(struct sockaddr*)&their_addr,sizeof(struct sockaddr)));printf("Get the Server~\n");numbytes &#61; recv(sockfd, buf, BUFSIZ,0);buf[numbytes]&#61;&#39;\0&#39;; printf("buf: %s\n",buf);while(1){printf("Entersome thing:");scanf("%[^\n]%*c",buf);printf("scanf: %s\n", buf);numbytes &#61; send(sockfd, buf, strlen(buf), 0);printf("send numbytes: %d\n", numbytes);numbytes&#61;recv(sockfd,buf,BUFSIZ,0); printf("recv numbytes: %d\n", numbytes);buf[numbytes]&#61;&#39;\0&#39;; printf("received:%s\n",buf); }close(sockfd);return 0;
}
效果展示
先启动服务端&#xff0c;再启动客户端
客户端
服务端