作者在 2010-10-15 12:49:58 发布以下内容
基础编程
(1)函数说明
进行socket编程的基本函数有socket、bind、listen、accept、send、sendto、recv、recvfrom这几个,其中对于客户端和服务器端以及 TCP 和 UDP 的操作流程都有所区别,这里先对每个函数进行一定的说明,再给出不同情况下使用的流程图。
socket:该函数用于建立一个socket连接,可指定socket类型等信息。在建立了socket连接之后,可对socketadd或sockaddr_in进行初始化,以保存所建立的 socket信息。
bind:该函数是用于将本地 IP 地址绑定端口号的,若绑定其他地址则不能成功。另外,它主要用于TCP的连接,而在UDP的连接中则无必要。
connect:该函数在TCP中是用于bind的之后的 client端,用于与服务器端建立连接,而在UDP中由于没有了bind函数,因此用connect有点类似 bind函数的作用。
send和recv:这两个函数用于接收和发送数据,可以用在 TCP中,也可以用在 UDP中。当用在UDP时,可以在connect函数建立连接之后再用。
sendto和recvfrom:这两个函数的作用与send和recv函数类型,也可以用在TCP和UDP中。当用在TCP时,后面的几个与地址有关参数不起作用,函数作用等同于 send和 recv;当用在UDP时,可以用在之前没有使用 connect的情况时,这两个函数可以自动寻找制定地址并进行连接。
#include <sys/socket.h>
int socket(int family, int type, int protocol) ;
int bind(int sockfd,struct sockaddr *my_addr, int addrlen) ;
int listen(int sockfd,int backlog);backlog:请求队列中允许的最大请求数,大多数系统缺省值为20
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
int send(int sockfd, const void *msg, int len, int flags) ;
int recv(int sockfd,void *buf,int len,unsigned int flags) ;
int sendto(int sockfd, const void *msg,int len,unsigned int flags,const struct sockaddr *to, int tolen) ;
int recvfrom(int sockfd,void *buf,int len,unsigned int flags,struct sockaddr *from,int *fromlen) ;
tcp中服务器程序设计
第一步调用sockte()建立一个套接字套接字其实就是个文件描述符包括(所用的协议+ip地址+端口号)
第二步设置 struct sockaddr_in结构体(第一步中的三个)
struct sockaddr_in server_sockaddr;
server_sockaddr.sin_family=AF_INET;//ip4协议
server_sockaddr.sin_port=hotns(SERVPORT);//设置端口
server_sockaddr.sin_addr.s_addr=INADDR_ANY;//设置ip地址
第三步调用bind();
第四步调用listen();
第五步:调用accept函数,等待客户端的连接
第六步:调用recv函数接受客户端的请求
/*server.c*/
#include<sys/types.h>
#include<sys/socket.h>
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#include<unistd.h>
#include<netinet/in.h>
#define SERVPORT 3333
#define BACKLOG 10
#define MAX_CONNECTED_NO 10
#define MAXDATASIZE 5
int main(void)
{
struct sockaddr_in server_sockaddr,client_sockaddr;
int sin_size,recvbytes;
int sockfd,client_fd;
char buf[MAXDATASIZE];
if((sockfd=sockte(AF_INET,SOCK_STREAM,0))==-1)//设置为流式套接字tcp
{
perror("socket");
exit(1);
}
printf("socket success!,sockfd=%d\n",sockfd);
/*设置sockaddr_in结构体中相关参数*/
server_sockaddr.sin_family=AF_INET;
server_sockaddr.sin_port=hotns(SERVPORT);
server_sockaddr.sin_addr.s_addr=INADDR_ANY;
bzero(&(server_sockaddr.sin_zero),8);
/*绑定函数bind*/
if(bind(sockfd,(struct sockaddr *)&server_sockaddr,sizeof(struct sockaddr))==-1)
{
perror("bind");
exit(1);
}
printf("bind success!\n");
/*调用listen 函数*/
if(listen(sockfd,BACKLOG)==-1)
{
perror("listen");
exit(1);
}
printf("listening.....\n");
/*调用accept函数,等待客户端的连接*/
if((client_fd=accept(sockfd,(struct sockaddr *)&client_sockaddr,&sin_size))==-1)
{
perror("accept");
exit(1);
}
/*调用recv函数接受客户端的请求*/
if((recvbytes=recv(client_fd,buf,MAXDATASIZE,0))==-1)
{
perror("recv");
exit(1);
}
printf("recvived a connection :%s \n",buf);
close(sockfd);
}
/*client.c*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define SERVPORT 3333
#define MAXDATASIZE 100
int main(int argc,char *argv[])
{
int sockfd,sendbytes;
char buf[MAXDATASIZE];
struct hostent *host;
struct sockaddr_in serv_addr;
if(argc < 2)
{
fprintf(stderr,"Please enter the server's hostname!\n");
exit(1);
}
/*地址解析函数*/
if((host=gethostbyname(argv[1]))==NULL)
{
perror("gethostbyname");
exit(1);
}
/*创建socket*/
if((sockfd=socket(AF_INET,SOCK_STREAM,0))== -1)
{
perror("socket");
exit(1);
}
/*设置sockaddr_in 结构体中相关参数*/
serv_addr.sin_family=AF_INET;
serv_addr.sin_port=htons(SERVPORT);
serv_addr.sin_addr=*((struct in_addr *)host->h_addr);
bzero(&(serv_addr.sin_zero),8);
/*调用connect函数主动发起对服务器端的连接*/
if(connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(struct sockaddr))== -1)
{
perror("connect");
exit(1);
}
/*发送消息给服务器端*/
if((sendbytes=send(sockfd,"hello",5,0))== -1)
{
perror("send");
exit(1);
}
close(sockfd);
}
(1)函数说明
进行socket编程的基本函数有socket、bind、listen、accept、send、sendto、recv、recvfrom这几个,其中对于客户端和服务器端以及 TCP 和 UDP 的操作流程都有所区别,这里先对每个函数进行一定的说明,再给出不同情况下使用的流程图。
socket:该函数用于建立一个socket连接,可指定socket类型等信息。在建立了socket连接之后,可对socketadd或sockaddr_in进行初始化,以保存所建立的 socket信息。
bind:该函数是用于将本地 IP 地址绑定端口号的,若绑定其他地址则不能成功。另外,它主要用于TCP的连接,而在UDP的连接中则无必要。
connect:该函数在TCP中是用于bind的之后的 client端,用于与服务器端建立连接,而在UDP中由于没有了bind函数,因此用connect有点类似 bind函数的作用。
send和recv:这两个函数用于接收和发送数据,可以用在 TCP中,也可以用在 UDP中。当用在UDP时,可以在connect函数建立连接之后再用。
sendto和recvfrom:这两个函数的作用与send和recv函数类型,也可以用在TCP和UDP中。当用在TCP时,后面的几个与地址有关参数不起作用,函数作用等同于 send和 recv;当用在UDP时,可以用在之前没有使用 connect的情况时,这两个函数可以自动寻找制定地址并进行连接。
#include <sys/socket.h>
int socket(int family, int type, int protocol) ;
int bind(int sockfd,struct sockaddr *my_addr, int addrlen) ;
int listen(int sockfd,int backlog);backlog:请求队列中允许的最大请求数,大多数系统缺省值为20
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
int send(int sockfd, const void *msg, int len, int flags) ;
int recv(int sockfd,void *buf,int len,unsigned int flags) ;
int sendto(int sockfd, const void *msg,int len,unsigned int flags,const struct sockaddr *to, int tolen) ;
int recvfrom(int sockfd,void *buf,int len,unsigned int flags,struct sockaddr *from,int *fromlen) ;
tcp中服务器程序设计
第一步调用sockte()建立一个套接字套接字其实就是个文件描述符包括(所用的协议+ip地址+端口号)
第二步设置 struct sockaddr_in结构体(第一步中的三个)
struct sockaddr_in server_sockaddr;
server_sockaddr.sin_family=AF_INET;//ip4协议
server_sockaddr.sin_port=hotns(SERVPORT);//设置端口
server_sockaddr.sin_addr.s_addr=INADDR_ANY;//设置ip地址
第三步调用bind();
第四步调用listen();
第五步:调用accept函数,等待客户端的连接
第六步:调用recv函数接受客户端的请求
/*server.c*/
#include<sys/types.h>
#include<sys/socket.h>
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#include<unistd.h>
#include<netinet/in.h>
#define SERVPORT 3333
#define BACKLOG 10
#define MAX_CONNECTED_NO 10
#define MAXDATASIZE 5
int main(void)
{
struct sockaddr_in server_sockaddr,client_sockaddr;
int sin_size,recvbytes;
int sockfd,client_fd;
char buf[MAXDATASIZE];
if((sockfd=sockte(AF_INET,SOCK_STREAM,0))==-1)//设置为流式套接字tcp
{
perror("socket");
exit(1);
}
printf("socket success!,sockfd=%d\n",sockfd);
/*设置sockaddr_in结构体中相关参数*/
server_sockaddr.sin_family=AF_INET;
server_sockaddr.sin_port=hotns(SERVPORT);
server_sockaddr.sin_addr.s_addr=INADDR_ANY;
bzero(&(server_sockaddr.sin_zero),8);
/*绑定函数bind*/
if(bind(sockfd,(struct sockaddr *)&server_sockaddr,sizeof(struct sockaddr))==-1)
{
perror("bind");
exit(1);
}
printf("bind success!\n");
/*调用listen 函数*/
if(listen(sockfd,BACKLOG)==-1)
{
perror("listen");
exit(1);
}
printf("listening.....\n");
/*调用accept函数,等待客户端的连接*/
if((client_fd=accept(sockfd,(struct sockaddr *)&client_sockaddr,&sin_size))==-1)
{
perror("accept");
exit(1);
}
/*调用recv函数接受客户端的请求*/
if((recvbytes=recv(client_fd,buf,MAXDATASIZE,0))==-1)
{
perror("recv");
exit(1);
}
printf("recvived a connection :%s \n",buf);
close(sockfd);
}
/*client.c*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define SERVPORT 3333
#define MAXDATASIZE 100
int main(int argc,char *argv[])
{
int sockfd,sendbytes;
char buf[MAXDATASIZE];
struct hostent *host;
struct sockaddr_in serv_addr;
if(argc < 2)
{
fprintf(stderr,"Please enter the server's hostname!\n");
exit(1);
}
/*地址解析函数*/
if((host=gethostbyname(argv[1]))==NULL)
{
perror("gethostbyname");
exit(1);
}
/*创建socket*/
if((sockfd=socket(AF_INET,SOCK_STREAM,0))== -1)
{
perror("socket");
exit(1);
}
/*设置sockaddr_in 结构体中相关参数*/
serv_addr.sin_family=AF_INET;
serv_addr.sin_port=htons(SERVPORT);
serv_addr.sin_addr=*((struct in_addr *)host->h_addr);
bzero(&(serv_addr.sin_zero),8);
/*调用connect函数主动发起对服务器端的连接*/
if(connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(struct sockaddr))== -1)
{
perror("connect");
exit(1);
}
/*发送消息给服务器端*/
if((sendbytes=send(sockfd,"hello",5,0))== -1)
{
perror("send");
exit(1);
}
close(sockfd);
}