linux应用程序编程之tcp

作者在 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);
}

        
默认分类 | 阅读 1188 次
文章评论,共1条
变幻小子
2011-03-20 19:57
1
游客请输入验证码
浏览48273次
文章分类