F_UNIX 地址系列(使用 AF_UNIX 或 AF_UNIX_CCSID 地址系列的套接字)可以是面向连接的(类型 SOCK_STREAM),也可以是无连接的(类型 SOCK_DGRAM)。两种类型都很可靠,原因是没有连接两个进程的外部通信函数。
套接字事件流:使用 AF_UNIX 地址系列的客户机应用程序
示例:使用 AF_UNIX 地址系列的客户机应用程序使用以下函数调用序列:
socket() 函数返回表示端点的套接字描述符。该语句还标识将对此套接字使用带有流传输(SOCK_STREAM)的 UNIX 地址系列。该函数返回表示端点的套接字描述符。还可使用 socketpair() 函数初始化 UNIX 套接字。
AF_UNIX 或 AF_UNIX_CCSID 是支持 socketpair() 函数的唯一地址系列。socketpair() 函数返回未命名的和已连接的套接字描述符。
服务端
--->socket()-----
为了建立socket,程序可以调用socket函数,该函数返回一个类似于文件描述符的句柄。
socket函数原型为:
int socket(int domain, int type, int protocol);
--->band()-----
bind函数将socket与本机上的一个端口相关联,随后你就可以在该端口监听服务请求。
bind函数原型为:
int bind(int sockfd,struct sockaddr*my_addr, int addrlen);
--->listen()
listen函数使socket处于被动的监听模式,并为该socket建立一个输入数据队列,将到达的服务请求保存在此队列中,直到程序处理它们
int listen(int sockfd, int backlog);
--->accept()
accept()函数让服务器接收客户的连接请求。在建立好输入队列后,服务器就调用accept函数,然后睡眠并等待客户的连接请求.
int accept(int sockfd, void*addr, int*addrlen);
--->recv()
send()和recv()这两个函数用于面向连接的socket上进行数据传输。
int recv(int sockfd,void*buf,int len,unsigned int flags);
--->send()
int send(int sockfd, const void*msg, int len, int flags);
--->close()与--->int shutdown(int sockfd,int how);
参数 how允许为shutdown操作选择以下几种方式:
·0-------不允许继续接收数据
·1-------不允许继续发送数据
·2-------不允许继续发送和接收数据,
·均为允许则调用close()
shutdown在操作成功时返回0,在出现错误时返回-1并置相应errno。
客户端
--->socket()
--->connect()
面向连接的客户程序使用connect函数来配置socket并与远端服务器建立一个TCP连接,
其函数原型为:int connect(int sockfd, struct sockaddr*serv_addr,int addrlen);
--->send()
--->recv()
--->close();
关系:connect()(客户端)---建立连接--->accept()(服务端);
send()(客户端)------数据(请求)------>recv()(服务端)
recv()(客户端)------数据(应答)------->send()(服务端)
客户端
//客户端
//g++ -o listenet.o listenet.c -lsocket -lnsl
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <time.h>
#include <iostream>
using namespace std;
int main()
//int listen_socket()
{
int sockfd,numbytes;
char buf[256];
struct sockaddr_in ser_addr;
char *p;
//int i = 0;
//将基本名字和地址转换
//建立一个TCP套接口
if((sockfd = socket(AF_INET,SOCK_STREAM,0))==-1)
{
perror("socket");
printf("create socket error.建立一个TCP套接口失败");
exit(1);
}
//初始化结构体,连接到服务器的2323端口
ser_addr.sin_family = AF_INET;
ser_addr.sin_port = htons(2323);
//their_addr.sin_addr = *((struct in_addr *)he->h_addr);
inet_aton( "192.168.0.101", &ser_addr.sin_addr );
bzero(&(ser_addr.sin_zero),8);
//和服务器建立连接
if(connect(sockfd,(struct sockaddr *)&ser_addr,sizeof(struct sockaddr))==-1)
{
perror("connect");
printf("create connect error");
exit(1);
}
//向服务器发送数据
int i= 0;
if(send(sockfd,"123456789",14,0)==-1)
{
perror("send");
printf("send error");
exit(1);
}
//接受从服务器返回的信息
if((numbytes = recv(sockfd,buf,256,0))==-1)
{
perror("recv");
printf("recv error");
exit(1);
}
//buf[numbytes] = '\0';
printf("Recive from server:%s\n",buf);
p=strtok(buf,"*");
while(p!=NULL)
{
printf("\n");
printf(p);
// m=strtok(buf,p);
p=strtok(NULL,"*");
//printf(p);
printf("\n");
}
//关闭socket
close(sockfd);
return 0;
}
服务端:
//服务端
#include "user.h"
//int g_listenfd;
pthread_mutex_t g_mutex;//定义互斥量
GlobalVarDefine globalData;
int sock_fd,new_fd;
struct sockaddr_in my_addr;//本机地址信息
struct sockaddr_in their_addr;//客户端地址信息
int sin_size;
int maxThread;
TYPETHREADVALUE *g_ThreadData;
int main()
{
int ret;
int *array;
char p_maxthread [20];
char user[10];
char passwd[10];
char trns[10];
char tmpStr[256] = {0};
strcpy(user,"bill");
strcpy(passwd,"billapp");
strcpy(trns,"billapp");
//int max;
//建立TCP套接口
if((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket create error!");
exit(1);
}
//初始化结构体,并绑定2323端口
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(2323);
my_addr.sin_addr.s_addr =INADDR_ANY;
bzero(&(my_addr.sin_zero),8);
//绑定套接口
if(bind(sock_fd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1)
{
perror("bind error !");
exit(1);
}
//创建监听套接口
if(listen(sock_fd, 10) == -1)
{
perror("listen error!");
exit(1);
}
//读取最大线程数
open_file( p_maxthread);
maxThread=atol(p_maxthread);
/*初始化全局的锁变量*/
pthread_mutex_init( &g_mutex, NULL );
g_ThreadData =(TYPETHREADVALUE*)calloc(sizeof(TYPETHREADVALUE),maxThread);
if( g_ThreadData == NULL )
{
printf("calloc memory error.");
return -1;
}
else
{
memset( g_ThreadData, 0, sizeof(TYPETHREADVALUE)*maxThread );
}
array = (int *) calloc( sizeof(int), maxThread );
if( array == NULL )
{
printf("calloc memory error");
return -1;
}
else
{
memset( array, 0, sizeof(int)*maxThread );
}
for( int thd_i = 0; thd_i < maxThread; thd_i++ )
{
array[thd_i] = thd_i;
ret = _DB_Connect(tmpStr, &g_ThreadData[thd_i].dbSession, user ,passwd ,trns );
if( ret != 0 )
{
printf("_DB_Connect -Error \n");
return 1;
}
ret = pthread_create(&g_ThreadData[thd_i].plthread,NULL, thread_function, (void*)&(array[thd_i]));
{
printf("Create DealTask thread error");
return -1;
}
}
while( 1 )
{
for( int thd_i = 0; thd_i < maxThread; thd_i++ )
{
if( g_ThreadData[thd_i].flag != 0 )
{
continue;
}
}
sleep(10);
}
pthread_mutex_destroy( &g_mutex );//收回互斥量资源
return 0;
}
void *thread_function(void *i)
{
/**子线程下标转化**/
int id = *(int*)i;
int client;
int numbytes;
char buff[256];
//等待连接
while(1)
{
/**子线程控制信号量**/
g_ThreadData[id].flag = 1;
printf("g_ThreadData[id]=%d\n",id);
if(pthread_mutex_lock(&g_mutex)!=0) /*对互斥量加锁*/
{
perror("Lock failed");
exit(1);
}
else
printf("main lock\n");
printf("I get it,my tid is %d\n",pthread_self());
printf("id=%d \n",id);
sin_size = sizeof(struct sockaddr_in);
if((new_fd = accept(sock_fd, (struct sockaddr *)&their_addr, (socklen_t*)&sin_size)) == -1)
{
perror("accept error");
continue;
}
if(pthread_mutex_unlock(&g_mutex)!=0) /*对互斥量解锁*/
{
perror("unlock failed");
exit(1);
}
else
printf("main unlock\n");
printf("accept success.\n");
printf("received a connection from IP is: %s \n",inet_ntoa(their_addr.sin_addr) );
//生成一个子进程来完成和客户端的会话,父进程继续监听
printf("create new thred success.\n");
//收到客户端的请求
memset(buff,0,256);
if((numbytes = recv(new_fd,buff,sizeof(buff),0))==-1)
{
perror("recv");
exit(1);
}
//调用函数
getBillCycleId(buff, g_ThreadData[id].dbSession);
//将从客户端接收到的信息再发回客户端
printf("sizeof(globalData.Date)=%d\n",sizeof(globalData.Date));
//通过分析将客户端的请求要的数据返回给客户端
if(send(new_fd,globalData.Date,sizeof(globalData.Date),0)==-1)
{
perror("send");
}
sleep(5);
/**子线程控制信号量**/
g_ThreadData[id].flag = 0;
}
/*user.h*/
#include<iostream>
#include"Database.h"
#include<stdio.h>
#include<string>
#include<fstream>
#include <time.h>
#include <errno.h>
#include <strings.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#include <fcntl.h>
#include <thread.h>
#define MAX 10
using namespace std;
/*全局变量结构体*/
typedef struct {
char Acct_id[14];
char Acct_balance_id[14] ; /*最大线程数*/
char Balance_type_id[9];
char balance[12];
char Eff_date[20];
char Exp_date[20];
char Date[200];
/*物理数据库用户密码数据库名*/
} GlobalVarDefine;
//全局的配置信息结构
extern GlobalVarDefine globalData;
typedef struct
{
pthread_t plthread;
DB_SESSION dbSession;
//int maxThread;
int flag;
}TYPETHREADVALUE;
/*typedef struct
{
char tmpStr[256];
}DB_RECORD_THREAD;*/
int getBillCycleId(char *buff,DB_SESSION dbSession);
int open_file(char p_maxthread[50]);//读取线程数
void *thread_function(void *i); /*线程入口函数*/
以上只是客户端与服务端的程序,连接数据库部分没有些,只有个函数,这是我写的一点,大家多多交流····