Linux下socket通信和多线程
服务端socket流程:socket() –> bind() –> listen() –> accept() –> 读取、发送信息(recv,send等)
客户端socket流程:socket() –> connect() –> 发送、读取信息(send,recv等)
参考:Socket基本操作
本文包含基本实现,多线程版本
基本实现
服务端监听某个端口,客户端连接之后发送数据——>客户端断开连接后,服务端也关闭了
服务端:
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h> const int Port = ; int main(void){
int sock_fd;
struct sockaddr_in mysock;
struct sockaddr_in client_addr;
int new_fd;
socklen_t sin_size
char buf[];
char sedbuf[] = "recv successfully.\n"; //初始化socket
sock_fd = socket(AF_INET,SOCK_STREAM,); //编辑地址信息
memset(&mysock,,sizeof(mysock));
mysock.sin_family = AF_INET;
mysock.sin_port = htons(Port);
mysock.sin_addr.s_addr = INADDR_ANY; //绑定地址,然后监听
bind(sock_fd,(struct sockaddr *)&mysock,sizeof(struct sockaddr));
if(listen(sock_fd,) < -){
printf("listen error.\n");
} sin_size = sizeof(struct sockaddr_in); printf("listening...\n");
new_fd = accept(sock_fd, (struct sockaddr *)&client_addr, &sin_size);//accpet
while(){
int len = recv(new_fd,buf,sizeof(buf),);
fputs(buf,stdout);
send(new_fd, sedbuf, sizeof(sedbuf), );
if(strcmp(buf,"exit\n") == ){
break;
}
memset(buf,,sizeof(buf));
}
close(new_fd);
close(sock_fd);
return ;
客户端:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#include<string.h>
#include<errno.h> const int Port = ; int main(void){
int sock_fd;
char buf[], sendbuf[], recvbuf[];
struct sockaddr_in server_addr;
sock_fd = socket(AF_INET, SOCK_STREAM, );//初始化socket
if(sock_fd == -){
printf("%s\n",strerror(errno));
return ;
} bzero(&server_addr, sizeof(server_addr));//编辑服务端地址信息
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(Port);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY); int tmp = connect(sock_fd, (struct sockaddr *)(&server_addr),
sizeof(struct sockaddr));//连接服务端socket
if(tmp == -){
printf("%s\n",strerror(errno));
return ;
} while(){
fgets(sendbuf, sizeof(sendbuf), stdin);
send(sock_fd, sendbuf, strlen(sendbuf), );
if(strcmp(sendbuf, "exit\n") == )
break;
recv(sock_fd, recvbuf, sizeof(recvbuf), );
fputs(recvbuf, stdout);
memset(sendbuf, , sizeof(sendbuf));
memset(recvbuf, , sizeof(recvbuf));
}
close(sock_fd);
return;
}
多客户端与服务端通信(多线程)
只需在服务端修改,增加多线程,就可以同时接收多个客户端发送的信息了。
服务端:
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h> const int Port = ;
pthread_mutex_t g_mutext; struct pthread_data{
struct sockaddr_in client_addr;
int sock_fd;
}; void *serveForClient(void * arg); int main(void){
int sock_fd;
struct sockaddr_in mysock;
struct pthread_data pdata;
pthread_t pt;
socklen_t sin_size = sizeof(struct sockaddr_in);
struct sockaddr_in client_addr;
int new_fd; //初始化socket
sock_fd = socket(AF_INET,SOCK_STREAM,); //编辑地址信息
memset(&mysock, , sizeof(mysock));
mysock.sin_family = AF_INET;
mysock.sin_port = htons(Port);
mysock.sin_addr.s_addr = INADDR_ANY; //绑定地址,然后监听
bind(sock_fd,(struct sockaddr *)&mysock,sizeof(struct sockaddr));
if(listen(sock_fd,) < -){
printf("listen error.\n");
} printf("listening...\n");
while(){
//accpet
new_fd = accept(sock_fd, (struct sockaddr *)&client_addr, &sin_size);
pdata.client_addr = client_addr;
pdata.sock_fd = new_fd;
pthread_create(&pt, NULL, serveForClient, (void *)&pdata);
}
close(new_fd);
close(sock_fd);
return ;
} void *serveForClient(void *arg){
struct pthread_data *pdata = (struct pthread_data*)arg;
int new_fd = pdata->sock_fd;
char recvbuf[];
char sendbuf[] = "recv successfully.\n";
while(){
recv(new_fd, recvbuf, sizeof(recvbuf), );
fputs(recvbuf,stdout);
strcpy(sendbuf, recvbuf);
if(strcmp(recvbuf,"exit\n") == ){
send(new_fd, "connection close.\n", sizeof("connection close.\n"), );
break;
}
send(new_fd, sendbuf, sizeof(sendbuf), );
memset(recvbuf,,sizeof(recvbuf));
}
//close(new_fd);评论中指出多了一次close,所以这里不close了,留待main函数中统一close
pthread_exit();
}
Linux下socket通信和多线程的更多相关文章
- Linux 下socket通信终极指南(附TCP、UDP完整代码)
linux下用socket通信,有TCP.UDP两种协议,网上的很多教程把两个混在了一起,或者只讲其中一种.现在我把自己这两天研究的成果汇总下来,写了一个完整的,适合初学者参考,也方便自己以后查阅. ...
- Linux下socket通信和epoll
上一篇博客用多线程实现服务端和多个客户端的通信,但是在实际应用中如果服务端有高并发的需求,多线程并不是一个好选择. 实现高并发的一种方法是IO多路复用,也就是select,poll,epoll等等. ...
- (8)Linux(客户端)和Windows(服务端)下socket通信实例
Linux(客户端)和Windows(服务端)下socket通信实例: (1)首先是Windows做客户端,Linux做服务端的程序 Windows Client端 #include <st ...
- Linux下进程通信的八种方法
Linux下进程通信的八种方法:管道(pipe),命名管道(FIFO),内存映射(mapped memeory),消息队列(message queue),共享内存(shared memory),信号量 ...
- linux下socket编程实例
linux下socket编程实例一.基本socket函数Linux系统是通过提供套接字(socket)来进行网络编程的.网络的socket数据传输是一种特殊的I/O,socket也是一种文件描述符.s ...
- Linux下Socket编程的端口问题( Bind error: Address already in use )
Linux下Socket编程的端口问题( Bind error: Address already in use ) 在进行linux网络编程时,每次修改了源代码并再次编译运行时,常遇到下面的地使用错误 ...
- linux下串口通信与管理
linux下的串口与windows有一些区别,下面将介绍一下linux下串口通信管理 查看是否支持USB串口: #lsmod | grep usbserial 如果没有信息:sudo apt-get ...
- UNIX下socket通信 - UDP通信
一.UNIX下socket通信: socket套接字是一种可以进行网络通信的内核对象,它是一个唯一的标示符,一般称它为socket描述符. 注意:UDP通信需要客户端先发送消息,服务端先进行等待客户端 ...
- Linux下socket编程基本知识
本文档主要讲解了Linux下socket编程的一些基本知识,主要包括套接字和字节序的概念,以及一些常用的结构体和函数. 本文是在网易云课堂学习过程中的记录,这个老师讲得很不错,推荐大家围观. Linu ...
随机推荐
- BZOJ 4517--[Sdoi2016]排列计数(乘法逆元)
4517: [Sdoi2016]排列计数 Time Limit: 60 Sec Memory Limit: 128 MBSubmit: 1727 Solved: 1067 Description ...
- Mysql的Text和Blob的比较
MySQL存在text和blob: (1)相同 在TEXT或BLOB列的存储或检索过程中,不存在大小写转换,当未运行在严格模式时,如果你为BLOB或TEXT列分配一个超过该列类型的最大长度的值,值被截 ...
- 双11,自动领取优惠券 js 代码
http://www.zhihu.com/question/36426051/answer/67690322 本来我不熟悉 js,正好研究一下 (function(window, document) ...
- Codeforces Round #452 (Div. 2) C. Dividing the numbers(水)
C. Dividing the numbers Petya has n integers: 1, 2, 3, ..., n. He wants to split these integers in t ...
- 近期js
1 var value1 = 0, value2 = 0, value3 = 0; for ( var i = 1; i <= 3; i++) { var i2 = i; (function() ...
- collectd+influxdb+grafana
今天一天都在弄这个,最终发现在配置grafana的时候选择influxdb的版本时候选错了.(挠头~~~!!!) collectd的配置还算简单,基本看过配置文件就比较清楚. influxdb(Go ...
- 解决org.hibernate.QueryException illegal attempt to dereference collection 异常错误
今天做项目的时候,有两个实体:款式.品牌两者关系是多对多的关联关系,实现的功能是:通过选择款式,显示出该款式的所有品牌.HQL语句如下: 运行时出现这个异常错误:org.hibernate.Query ...
- Python小白学习之路(二十一)—【迭代器】
迭代器 1.迭代器协议 对象必须提供一个 next 方法,执行该方法要么返回迭代中的下一项,要么就引起一个Stoplteration异常,以终止迭代(只能往后走不能往前退) 2.可迭代对象 实现了迭代 ...
- Andrew Ng机器学习第五章——多变量线性回归
一.多变量线性回归的技巧之一——特征缩放 1.为什么要使用特征缩放? 特征缩放用来确保特征值在相似的范围之内. 设想这样一种情况(房价预测),两个特征值分别是房子的大小和卧室的数量.每个特征值所处的范 ...
- Android 开发工具类 16_NotificationActivity
在前台运行的 Activity 可以通过Dialog.Toast 向用户发出提示信息,而后台运行的程序,如下载.收到信息等 Service 应用,则需要使用 Notification(通知)向用户发出 ...