linux基础编程 套接字socket 完整的服务器端多线程socket程序【转】
转自:http://blog.csdn.net/ghostyu/article/details/7737203
此段程序来自我的一个项目中,稍微做了些修改,运行稳定,客户端程序比较简单所以未编写,可以用socket调试工具测试此段代码
费话不多说,直接上代码
[cpp] view plain copy
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<errno.h>
#include<netdb.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<sys/wait.h>
#include<unistd.h>
#include<pthread.h>
#include<fcntl.h>
#define __DEBUG
#ifdef __DEBUG
#define DBG(fmt,args...) fprintf(stdout, fmt, ##args)
#else
#define DBG(fmt,args...)
#endif
#define ERR(fmt,args...) fprintf(stderr, fmt, ##args)
/*
isStreamQuit == 0 :Start
isStreamQuit == 1 :Client Quit
isStreamQuit ==-1 :App Quit
*/
static int isStreamQuit = ;
static int gStreamServerFd = -;
int gStreamClientFd;
#define PORT_SOCKET 9000 //server监听端口
#define RECV_BUF_MAX_LEN 512
#define TIME_WAIT 200000 /*200ms*/
/*
socket发送函数
*/
int ScketSend(unsigned char *buf,unsigned int len)
{
int ret = ;
if(gStreamClientFd <= )
return -;
ret = send(gStreamClientFd,buf,len,);
if(ret <= ){
return -;
}else if(ret == len){
return ;
}
while(ret < len){
ret += send(gStreamClientFd,buf+ret,len-ret,);
}
return ;
}
/*
socket连接线程,阻塞等待客户端的连接,
连接后循环处理客户端发来的数据,
这里只能连接一个客户端,稍加修改,就可以支持多客户端连接
*/
void *SocketThread(void *arg)
{
fd_set SockRead;
struct timeval TimeOut;
int ret;
struct sockaddr clientAddr;
unsigned char *rcvBuf = (unsigned char *)malloc(RECV_BUF_MAX_LEN);
socklen_t len;
len = sizeof(clientAddr);
while(){
int rcvLen;
/*阻塞等待客户端连接*/
gStreamClientFd = accept(gStreamServerFd, &clientAddr, &len);
if(gStreamClientFd == -){
ERR("ERROR in stream accept: %s\n",strerror(errno));
/*add errno handler here,in some case,the error is not fatal*/
/*code here*/
break;
}
/*isStreamQuit == -1,is the siganl to quit*/
if(isStreamQuit != -){
isStreamQuit = ;
}
DBG("accep a stream client\n");
/*客户端已连接,循环处理*/
while(isStreamQuit==){
FD_ZERO(&SockRead);
FD_SET(gStreamClientFd,&SockRead);
TimeOut.tv_sec = ;
TimeOut.tv_usec = TIME_WAIT;
/*
200ms超时判断是否有数据接收,有则接收,没有继续循环,
总是让程序不能一直阻塞在这里
*/
ret = select(gStreamClientFd+,&SockRead,NULL,NULL,&TimeOut);
if(ret == -){
ERR("ERROR in select\n");
break;
}else if(ret == ){
continue;
}
/*接收客户端发来的数据*/
rcvLen = recv(gStreamClientFd,rcvBuf,RECV_BUF_MAX_LEN,);
if(rcvLen < ){
ERR("ERROR in stream accept: %s\n",strerror(errno));
/*add errno handler here,in some case,the error is not fatal*/
/*code here*/
isStreamQuit = ;
break;
}else if(rcvLen == ){
DBG("stream client close\n");
/*code here*/
isStreamQuit = ;
break;
}
DBG("rcvLen: %d,rcvBuf: %s\n",rcvLen,rcvBuf);
memset(rcvBuf,,RECV_BUF_MAX_LEN);
}
DBG("Close Stream Socket\n");
close(gStreamClientFd);
/*OTHER Error or App Quit*/
if(isStreamQuit == -){
break;
}
}
DBG("SocketThread exit\n");
free(rcvBuf);
close(gStreamServerFd);
pthread_exit(NULL);
}
/*
socket连接初始化
*/
int SocketInit()
{
struct sockaddr_in server;
pthread_t tStreamSocketThr;
/*创建socket*/
gStreamServerFd = socket(AF_INET,SOCK_STREAM,);
if(gStreamServerFd == - ){
ERR("ERROR in create Stream Socket!\n");
return -;
}
memset(&server,,sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(PORT_SOCKET);
server.sin_addr.s_addr = htonl(INADDR_ANY);
/*绑定监听端口*/
if(bind(gStreamServerFd ,(struct sockaddr*)&server,sizeof(server))== -){
ERR("ERROR in bind Stream Socket: %s\n",strerror(errno));
return -;
}
/*开始监听*/
if( listen(gStreamServerFd, ) == -){
ERR("ERROR in listen Stream Socket: %s\n",strerror(errno));
return -;
}
/*创建socket连接线程,用来处理监听的结果,比如有客户端连接等*/
pthread_create(&tStreamSocketThr,NULL,SocketThread,NULL);
/*release thread resource,so we not use pthread_join to waitting*/
pthread_detach(tStreamSocketThr);
return ;
}
#if 1
int main()
{
if(SocketInit() == -){
return -;
}
while(){
sleep();
}
/*notice to exit*/
isStreamQuit = -;
sleep();
if(gStreamServerFd){
close(gStreamServerFd);
}
DBG("SUCCESS in ConnectManageExit\n");
}
#endif
运行结果
[cpp] view plain copy
[root@localhost src]# ./socket_connect
accep a stream client
rcvLen: ,rcvBuf: helle
Close Stream Socket
accep a stream client
rcvLen: ,rcvBuf: hello
Close Stream Socket
accep a stream client
rcvLen: ,rcvBuf: hello
rcvLen: ,rcvBuf: hello
rcvLen: ,rcvBuf: helle
Close Stream Socket
linux基础编程 套接字socket 完整的服务器端多线程socket程序【转】的更多相关文章
- python基础(29):网络编程(软件开发架构、网络基础、套接字初使用)
1. 软件开发架构 我们了解的程序之间通讯的应用可分为两种: 第一种是应用类:qq.微信.百度网盘.腾讯视频这一类是属于需要安装的桌面应用. 第二种是web类:比如百度.知乎.博客园等使用浏览器访问就 ...
- linux基础编程:IO模型:阻塞/非阻塞/IO复用 同步/异步 Select/Epoll/AIO(转载)
IO概念 Linux的内核将所有外部设备都可以看做一个文件来操作.那么我们对与外部设备的操作都可以看做对文件进行操作.我们对一个文件的读写,都通过调用内核提供的系统调用:内核给我们返回一个file ...
- UNIX网络编程——套接字选项(SO_REUSEADDR)
1.一般来说,一个端口释放后会等待两分钟之后才能再被使用,SO_REUSEADDR是让端口释放后立即就可以被再次使用. SO_REUSEADDR用于对TCP套接字处于TIME_WAIT状态下的sock ...
- 网络编程 套接字socket TCP UDP
网络编程与套接字 网络编程 网络编程是什么: 网络通常指的是计算机中的互联网,是由多台计算机通过网线或其他媒介相互链接组成的 编写基于网络的应用程序的过程序称之为网络编程. 网络编程最主要的工 ...
- Linux编程---套接字
网络相关的东西差点儿都是建立在套接字之上.所以这个内容对于程序猿来说还是蛮重要的啊. 事实上套接字也就是一个特殊的设备文件而已,我始终不能明确为什么要叫套接字.这么个奇怪的名字.只是还是就这样算了吧. ...
- [linux basic基础]----套接字
套接字是一种通信机制,凭借这种机制client/server系统的开发者既可以在本地机器上进行,也可以跨网络进行. 1,服务器应用程序用系统调用socket来创建一个套接字,他是系统分配给服务器进程的 ...
- Java网络编程--套接字Socket
一.套接字Socket IP地址标志Internet上的计算机,端口号标志正在计算机上运行的进程(程序). 端口号被规定为一个16位的0--65535之间的整数,其中,0--1023被预先定义的服务通 ...
- 流式套接字:基于TCP协议的Socket网络编程(案例3)
案例:在案例1的基础上将传输的字符串换成具体的对象. 客户端代码: package com.yh.SocketObject; import java.io.IOException; import ja ...
- UNIX网络编程——套接字选项(心跳检测、绑定地址复用)
/* 设置套接字选项周期性消息检测连通性 心跳包. 心博.主要用于长连接. * 参数:套接字, 1或0开启, 首次间隔时间, 两次间隔时间, 断开次数 */ void setKeepAlive( in ...
随机推荐
- python学习总结----异常处理
相关概念 - 错误:程序运行之前的语法错误,如:关键字.缩进不齐.括号不成对. - 异常:在程序运行过程中出现的问题,如:除数为0.对象属性不存在等. 异常处理 - 说明:异常处理可以理解为特殊的流程 ...
- BZOJ 2049 SDOI2008 洞穴勘测 LCT板子
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2049 题意概述:给出N个点,一开始不连通,M次操作,删边加边,保证图是一个森林,询问两点连 ...
- markdown(自己看)
https://www.cnblogs.com/james-lee/p/6847906.html https://maxiang.io/
- 【Python】python中的__dict__,__getattr__,__setattr__
Python class 通过内置成员__dict__ 存储成员信息(字典) 首先用一个简单的例子看一下__dict__ 的用法 class A(): def __init__(self,ax,bx) ...
- WCF身份验证二:基于消息安全模式的自定义身份验证
使用X509证书进行身份验证应该说是WCF安全模型中最”正常”的做法, 因为WCF强制要求使用证书加密身份数据, 离开了证书, 所有的身份验证机制拒绝工作, WCF支持的身份验证机制也相当复杂, 这里 ...
- 一道ioccc题目
国际C语言混乱大赛的一个题: main() {printf(&unix["\021%six\012\0"],(unix)["have"]+"f ...
- [剑指Offer] 20.包含min函数的栈
题目描述 定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数. [思路1]两个栈Stack和Min,Stack为当前栈中元素,Min为与Stack中元素一一对应的当前栈最小值. cl ...
- 前端工程师必须要知道的SEO技巧(1):rel=nofollow的使用
前提:最近我在找工作,想面试一些关于前端的工作,被问到了一些关于SEO优化的问题.我深深的感觉我所回答的太过于表面,没有深入.所以,又把SEO的内容看了一遍.自己总结如下:有的是看的其他博友的贴子,发 ...
- BZOJ1143 [CTSC2008]祭祀river 【二分图匹配】
1143: [CTSC2008]祭祀river Time Limit: 10 Sec Memory Limit: 162 MB Submit: 3236 Solved: 1651 [Submit] ...
- BZOJ 3319 黑白树 并查集+线段树
这这这这这这什么毒瘤题!!!!!!!!!!!!!!!!!!!!!!!!!!!! 卡LCT(优秀的LCT由于是均摊本身就带着2,3的常数在,而且这道题对于LCT标记十分难维护,又得乘上4,5然后就炸了) ...