linux伺服器和客戶端中文會話客戶端
阿新 • • 發佈:2019-02-03
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<unistd.h>
#include<netinet/in.h>
#include <errno.h>
#include <sys/msg.h>
#include<iconv.h>
#define PORT 6666
#define MAX_TEXT 512
struct msg_st
{
long msg_type;
char text[BUFSIZ];
};
int gb2312toutf8( char *sourcebuf,size_t sourcelen,char *destbuf,size_t destlen) {
iconv_t cd; if( (cd = iconv_open("utf-8","gb2312")) ==0 )
return -1; memset(destbuf,0,destlen);
char **source = &sourcebuf;
char **dest = &destbuf;
if(-1 == iconv(cd,source,&sourcelen,dest,&destlen))
return -1;
iconv_close(cd);
return 0;
}
int main(int argc,char **argv)
{
int ser_sockfd,cli_sockfd;
int err,n;
int addlen;
struct sockaddr_in ser_addr;
struct sockaddr_in cli_addr;
char recvline[200],sendline[200];
char *p;
/*****************************************************************************/
int msgid = -1;
msgid = msgget((key_t)1234, 0666 | IPC_CREAT);//檔案儲存許可權是0666
if(msgid == -1)
{
fprintf(stderr, "msgget failed with error: %d\n", errno);
exit(EXIT_FAILURE);//程式執行失敗
}
/*****************************************************************************/
//建立伺服器本地socket監聽
ser_sockfd=socket(AF_INET,SOCK_STREAM,0);//建立一個socket
if(ser_sockfd==-1)
{
printf("socket error:%s\n",strerror(errno));
return -1;
}
int on;
on = 1;//開啟這個ON
//它由 TCP 套接字狀態 TIME_WAIT 引起。該狀態在套接字關閉後約保留 2 到 4 分鐘
//SO_REUSERADDR 允許重用本地地址和埠
setsockopt( ser_sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) );
bzero(&ser_addr,sizeof(ser_addr));
ser_addr.sin_family=AF_INET;
ser_addr.sin_addr.s_addr=htonl(INADDR_ANY);
ser_addr.sin_port=htons(PORT);
err=bind(ser_sockfd,(struct sockaddr *)&ser_addr,sizeof(ser_addr));//繫結本地IP和埠
if(err==-1)
{
printf("bind error:%s\n",strerror(errno));
return -1;
}
err=listen(ser_sockfd,5);//監聽埠,這裡範圍不知道
if(err==-1)
{
printf("listen error\n");
return -1;
}
printf("listen the port:\n");
/*****************************************************************************/
pid_t pid;
char *message;
//兩個fork建立了四個執行緒,接收中文亂碼可能是因為大小端的問題
//還沒弄懂程序的問題
//這裡僅僅是手機客戶端連線的程序
pid= fork();
fork();
if(pid < 0)
{
perror("fork failed\n");
exit(1);
}
/*****************************************************************************/
while(1)
{
addlen=sizeof(struct sockaddr);
//可以連線多個客戶端
cli_sockfd=accept(ser_sockfd,(struct sockaddr *)&cli_addr,&addlen);//非阻塞
if(cli_sockfd==-1)
{
printf("accept error\n");
break;
}
printf("連線上\n");//連線上了,不需要這裡返回資料,手機哪裡就可以查得到
while(1)
{
memset(recvline,0,200);
n=recv(cli_sockfd,recvline,200,0);//阻塞IO
if(0==n)
{
printf("TCP斷開連線\n");
break;
}
recvline[n]='\0';//這裡一定要加字串結束符號嗎?
char line[200];//排除干擾
strcpy(line, recvline);
char dest_utf8[200];
//這裡是把utf-8轉換成GB2312
gb2312toutf8(line,strlen(line),dest_utf8,200);
printf("\nreceive data :%s\n",dest_utf8);
/*****************************************************************************/
if(strstr(recvline,"phone"))
{
//建立訊息佇列
struct msg_st data;
int msgid = -1;
msgid = msgget((key_t)1234, 0666 | IPC_CREAT);
if(msgid == -1)
{
fprintf(stderr, "msgget failed with error: %d\n", errno);
//exit(EXIT_FAILURE);//沒寫???有問題不???
}
data.msg_type = 1;
strcpy(data.text, recvline);
if(msgsnd(msgid, (void*)&data, 200, IPC_NOWAIT) == -1)//不能大於1024
{
fprintf(stderr, "\n%d %s\n",errno,strerror(errno));
//exit(EXIT_FAILURE);
}
else
{
printf("\n加入訊息佇列成功\n");
}
}
/*****************************************************************************/
else
{
//可以過濾掉錯誤的資訊
char sendline[]="the error data\n";
send(cli_sockfd,sendline,strlen(sendline),0);//傳送失敗>才返回-1,關掉了如何判斷
}
usleep(50);
}
close(cli_sockfd);
}
close(ser_sockfd);
return 0;
}
#include<stdlib.h>
#include<string.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<unistd.h>
#include<netinet/in.h>
#include <errno.h>
#include <sys/msg.h>
#include<iconv.h>
#define PORT 6666
#define MAX_TEXT 512
struct msg_st
{
long msg_type;
char text[BUFSIZ];
};
int gb2312toutf8( char *sourcebuf,size_t sourcelen,char *destbuf,size_t destlen) {
iconv_t cd; if( (cd = iconv_open("utf-8","gb2312")) ==0 )
return -1; memset(destbuf,0,destlen);
char **source = &sourcebuf;
char **dest = &destbuf;
if(-1 == iconv(cd,source,&sourcelen,dest,&destlen))
return -1;
iconv_close(cd);
return 0;
}
int main(int argc,char **argv)
{
int ser_sockfd,cli_sockfd;
int err,n;
int addlen;
struct sockaddr_in ser_addr;
struct sockaddr_in cli_addr;
char recvline[200],sendline[200];
char *p;
/*****************************************************************************/
int msgid = -1;
msgid = msgget((key_t)1234, 0666 | IPC_CREAT);//檔案儲存許可權是0666
if(msgid == -1)
{
fprintf(stderr, "msgget failed with error: %d\n", errno);
exit(EXIT_FAILURE);//程式執行失敗
}
/*****************************************************************************/
//建立伺服器本地socket監聽
ser_sockfd=socket(AF_INET,SOCK_STREAM,0);//建立一個socket
if(ser_sockfd==-1)
{
printf("socket error:%s\n",strerror(errno));
return -1;
}
int on;
on = 1;//開啟這個ON
//它由 TCP 套接字狀態 TIME_WAIT 引起。該狀態在套接字關閉後約保留 2 到 4 分鐘
//SO_REUSERADDR 允許重用本地地址和埠
setsockopt( ser_sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) );
bzero(&ser_addr,sizeof(ser_addr));
ser_addr.sin_family=AF_INET;
ser_addr.sin_addr.s_addr=htonl(INADDR_ANY);
ser_addr.sin_port=htons(PORT);
err=bind(ser_sockfd,(struct sockaddr *)&ser_addr,sizeof(ser_addr));//繫結本地IP和埠
if(err==-1)
{
printf("bind error:%s\n",strerror(errno));
return -1;
}
err=listen(ser_sockfd,5);//監聽埠,這裡範圍不知道
if(err==-1)
{
printf("listen error\n");
return -1;
}
printf("listen the port:\n");
/*****************************************************************************/
pid_t pid;
char *message;
//兩個fork建立了四個執行緒,接收中文亂碼可能是因為大小端的問題
//還沒弄懂程序的問題
//這裡僅僅是手機客戶端連線的程序
pid= fork();
fork();
if(pid < 0)
{
perror("fork failed\n");
exit(1);
}
/*****************************************************************************/
while(1)
{
addlen=sizeof(struct sockaddr);
//可以連線多個客戶端
cli_sockfd=accept(ser_sockfd,(struct sockaddr *)&cli_addr,&addlen);//非阻塞
if(cli_sockfd==-1)
{
printf("accept error\n");
break;
}
printf("連線上\n");//連線上了,不需要這裡返回資料,手機哪裡就可以查得到
while(1)
{
memset(recvline,0,200);
n=recv(cli_sockfd,recvline,200,0);//阻塞IO
if(0==n)
{
printf("TCP斷開連線\n");
break;
}
recvline[n]='\0';//這裡一定要加字串結束符號嗎?
char line[200];//排除干擾
strcpy(line, recvline);
char dest_utf8[200];
//這裡是把utf-8轉換成GB2312
gb2312toutf8(line,strlen(line),dest_utf8,200);
printf("\nreceive data :%s\n",dest_utf8);
/*****************************************************************************/
if(strstr(recvline,"phone"))
{
//建立訊息佇列
struct msg_st data;
int msgid = -1;
msgid = msgget((key_t)1234, 0666 | IPC_CREAT);
if(msgid == -1)
{
fprintf(stderr, "msgget failed with error: %d\n", errno);
//exit(EXIT_FAILURE);//沒寫???有問題不???
}
data.msg_type = 1;
strcpy(data.text, recvline);
if(msgsnd(msgid, (void*)&data, 200, IPC_NOWAIT) == -1)//不能大於1024
{
fprintf(stderr, "\n%d %s\n",errno,strerror(errno));
//exit(EXIT_FAILURE);
}
else
{
printf("\n加入訊息佇列成功\n");
}
}
/*****************************************************************************/
else
{
//可以過濾掉錯誤的資訊
char sendline[]="the error data\n";
send(cli_sockfd,sendline,strlen(sendline),0);//傳送失敗>才返回-1,關掉了如何判斷
}
usleep(50);
}
close(cli_sockfd);
}
close(ser_sockfd);
return 0;
}