服务端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();
}

最新文章

  1. iOS学习之iOS沙盒(sandbox)机制和文件操作之NSFileManager(三)
  2. Android Studio新建了一个项目提示Error:Unable to start the daemon process
  3. Java和.net常用开发框架组合
  4. WinDbg 调试.net程序
  5. linux下手动安装apache详解
  6. 陈发树云南白药股权败诉真相 取胜仅差三步 z
  7. fingerprintjs
  8. hibernate自动建表采用UTF-8字符编码
  9. Linux菜鸟之路[4]-cal,date,bc,echo $LANG,man
  10. 转--htaccess语法教程 apache服务器伪静态规则教程
  11. js实现哈希表(HashTable)
  12. Anaconda+MINGW+theano+keras安装
  13. sdoi2017苹果树
  14. jsp中的JSTL与EL表达式用法及区别
  15. Mybatis学习3——动态代理
  16. MVC的JavaScriptResult使用
  17. IPhone手机页面中点击文本输入框,弹出键盘,网页会放大,如何解决
  18. 【java规则引擎】《Drools7.0.0.Final规则引擎教程》第4章 4.2 auto-focus
  19. 【OpenCV入门教程之二】 一览众山小:OpenCV 2.4.8 or OpenCV 2.4.9组件结构全解析
  20. eclipse Subversion Native Library Not Available

热门文章

  1. python小数的进位与舍去
  2. 639. Decode Ways II
  3. SpringBoot入门之分散配置
  4. PHP之旅6 php的类与面向对象
  5. PHP之旅5 php的函数
  6. git 查看提交记录
  7. POJ 1014
  8. Centos6.7安装Pycharm及升级JDK
  9. Win7上装CentOS7 双系统
  10. Java的符号扩展与零扩展