ubuntu下socket通信

来源:互联网 发布:淘宝新店铺怎么引流量 编辑:程序博客网 时间:2024/06/05 14:42

之前的博文介绍了如何在ubuntu下实现unix domain socket通信,但只是本地的通信,虽然过程和网络通信很类似,但这里还是有必要了解下真正的socket通信

首先贴出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>#include <pthread.h>#define PORT 4321#define BUFFER_SIZE 1024#define MAX_QUE_CONN_NM 5struct sockaddr_in server_sockaddr,client_sockaddr;int sin_size,recvbytes,sendbytes;int sockfd, client_fd;char buf[BUFFER_SIZE];char message[72];void *thrd_send(){while(1){    memset(buf, 0, sizeof(buf));    printf("请输入 message:\n");    scanf("%s",&message);    sprintf(buf, "%s", message);/*发送消息给服务器端*/if ((sendbytes = send(client_fd, buf, strlen(buf), 0)) == -1)        {        perror("send");        exit(1);        }     }}int main(){    pthread_t thread[1];/*建立 socket 连接*/if ((sockfd = socket(AF_INET,SOCK_STREAM,0))== -1)           {               perror("socket");               exit(1);           }   printf("Socket id = %d\n",sockfd);/*设置 sockaddr_in 结构体中相关参数*/  server_sockaddr.sin_family = AF_INET;  server_sockaddr.sin_port = htons(PORT);  server_sockaddr.sin_addr.s_addr = INADDR_ANY;  bzero(&(server_sockaddr.sin_zero), 8);  int i = 1;/* 允许重复使用本地地址与套接字进行绑定 */  setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));/*绑定函数 bind()*/    if (bind(sockfd, (struct sockaddr *)&server_sockaddr,sizeof(structsockaddr)) == -1)           {               perror("bind");               exit(1);           }    printf("Bind success!\n");/*调用 listen()函数,创建未处理请求的队列*/   if (listen(sockfd, MAX_QUE_CONN_NM) == -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);           }while(1){  memset(buf , 0, sizeof(buf));/*调用 recv()函数接收客户端的请求*/  if ((recvbytes = recv(client_fd, buf, BUFFER_SIZE, 0)) == -1)         {             perror("recv");             exit(1);         }   else if(recvbytes==0)  {  printf("失败\n");  exit(1);   }  printf("Received a message: %s\n", buf);  pthread_create(&thread[0],NULL,thrd_send,(void*)0); }close(sockfd);exit(0);}

在这里要注意的是端口port设定的是4321,也就是在client代码中,端口号要一致。

还有在server端的sockaddr结构体中,sin.addr.s.addr =INADDR_ANY;

INADDR_ANY:就是指定所有的ip地址,因为可能一个电脑上有多个网卡,也就是他有多个ip 地址,那么socket服务是监听哪一个ip呢,如果用INADDR_ANY就表示监听所有的ip地址,无论主机是从哪个ip地址接受到socket数据,都能被捕捉到,这个参数常用在server端。


client代码:

#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>#include <pthread.h>#define PORT 4321#define BUFFER_SIZE 1024int sockfd,sendbytes,recvbytes;char buf[BUFFER_SIZE];char ip[36];char message[72];struct hostent *host;struct sockaddr_in serv_addr;void *thrd_recv(){while(1){    memset(buf , 0, sizeof(buf));if ((recvbytes = recv(sockfd, buf, BUFFER_SIZE, 0)) == -1)           {              perror("recv");               exit(1);           }    printf("Received a message: %s\n", buf);      }}int main(){    pthread_t thread[1];    printf("请输入对方 IP 或者主机名\n");    scanf("%s",&ip);    printf("对方 IP 或者主机名是:%s\n",ip); if ((host = gethostbyname(ip) )== 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(PORT);    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(structsockaddr))== -1)        {        perror("connect");        exit(1);        }while(1){    pthread_create(&thread[0],NULL,thrd_recv,(void*)0);    memset(buf, 0, sizeof(buf));    printf("请输入 message:\n");    scanf("%s",&message);    sprintf(buf, "%s", message);/*发送消息给服务器端*/if ((sendbytes = send(sockfd, buf, strlen(buf), 0)) == -1)        {        perror("send");        exit(1);        }      }    close(sockfd);    exit(0);}

client端要注意的地方就是端口设置,要和server端一样,同时server端的ip地址设置为手动输入。

然后分别运行server端和client端,结果如下:



0 0
原创粉丝点击