///////////////////////////////////////////////////////////////////////////////
/*
gcc -Wall -o c1 c1.c -lws2_32
*/
///////////////////////////////////////////////////////////////////////////////

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>

#define _WIN32_WINNT 0x501
#define PORT 4000
#define IP_ADDRESS "127.0.0.1"
///////////////////////////////////////////////////////////////////////////////
// SK

#ifdef _WIN32_WINNT
#include <ws2tcpip.h>
#include <winsock2.h>
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/un.h>
#include <netdb.h>
#endif

///////////////////////////////////////////////////////////////////////////////
// SK

void connect_inet_socket( int *psockfd, const char* host, int port );

#ifdef _WIN32_WINNT
void connect_windows_socket( int *psockfd, const char* pathname );
#else
void connect_unix_socket( int *psockfd, const char* pathname );
#endif

void writebuffer_socket( int sockfd, const void *data, int len );
void readbuffer_socket( int sockfd, void *data, int len );
void shutdown_socket( int sockfd );

///////////////////////////////////////////////////////////////////////////////
// SK
/* Access to sockets needs to be done with a wrapper function 'connect_socket'
and it is substituted by 'connect_windows_socket' or by 'connect_unix_socket'
( depends on a state of the macro _WIN32 ) during preprocessing phase of
the compilation.
For portability 'connect_windows_socket' and 'connect_unix_socket' shouldn't
be used directly and the wrapper function 'connect_socket' must be used instead.
*/

#ifdef _WIN32_WINNT
#define connect_socket connect_windows_socket
#else
#define connect_socket connect_unix_socket
#endif

int socket_desc;
struct sockaddr_in server;

///////////////////////////////////////////////////////////////////////////////
/* Opens an internet socket.

Note that fortran passes an extra argument for the string length,
but this is ignored here for C compatibility.

Args:
psockfd: The id of the socket that will be created.
port: The port number for the socket to be created. Low numbers are
often reserved for important channels, so use of numbers of 4
or more digits is recommended.
host: The name of the host server.
*/

void connect_inet_socket( int *psockfd, const char* host, int port )
{
int sockfd, ai_err;

// creates an internet socket

// fetches information on the host
struct addrinfo hints, *res;
char service[256];

memset(&hints, 0, sizeof(hints));
hints.ai_socktype = SOCK_STREAM;
hints.ai_family = AF_UNSPEC;
hints.ai_flags = AI_PASSIVE;

//sprintf(service, "%d", port); // convert the port number to a string
//ai_err = getaddrinfo(host, service, &hints, &res);
//if (ai_err!=0) {
// printf("Error code: %i\n",ai_err);
// perror("Error fetching host data. Wrong host name?");
// exit(-1);
//}

// creates socket
//sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
sockfd = socket(AF_INET , SOCK_STREAM , IPPROTO_TCP);
if (sockfd < 0) {
perror("Error opening socket");
exit(-1);
}
else
{
printf("creates socket:%d\n", sockfd);
}

// makes connection
if (connect(sockfd, res->ai_addr, res->ai_addrlen) < 0) {
perror("Error opening INET socket: wrong port or server unreachable");
exit(-1);
}
freeaddrinfo(res);

*psockfd = sockfd;
}

///////////////////////////////////////////////////////////////////////////////
// SK
/* Opens a socket.

Note that fortran passes an extra argument for the string length,
but this is ignored here for C compatibility.

Args:
psockfd: The id of the socket that will be created.
pathname: The name of the file to use for sun_path.
*/

#ifdef _WIN32_WINNT

void connect_windows_socket( int *psockfd, const char* pathname )
{
// Required functionality for Windows

// ...
}

#else

void connect_unix_socket( int *psockfd, const char* pathname )
{
// Required functionality for Unix

int sockfd, ai_err;

struct sockaddr_in serv_addr;

printf("Connecting to :%s:\n",pathname);

// fills up details of the socket addres
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sun_family = AF_UNIX;
/* Beware of buffer over runs
UNIX Network Programming by Richard Stevens mentions
that the use of sizeof() is ok, but see
http://mail-index.netbsd.org/tech-net/2006/10/11/0008.html
*/
if ((int)strlen(pathname)> sizeof(serv_addr.sun_path)) {
perror("Error opening UNIX socket: pathname too long\n");
exit(-1);
} else {
strcpy(serv_addr.sun_path, pathname);
}
// creates a unix socket

// creates the socket
sockfd = socket(AF_UNIX, SOCK_STREAM, 0);

// connects
if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
perror("Error opening UNIX socket: path unavailable, or already existing");
exit(-1);
}
*psockfd = sockfd;
}

#endif

///////////////////////////////////////////////////////////////////////////////
/* Writes to a socket.

Args:
sockfd: The id of the socket that will be written to.
data: The data to be written to the socket.
len: The length of the data in bytes.
*/

void writebuffer_socket( int sockfd, const void *data, int len )
{
int n;

n = write(sockfd, (char *) data, len);
if (n < 0) {
perror("Error writing to socket: server has quit or connection broke");
exit(-1);
}
}

///////////////////////////////////////////////////////////////////////////////
/* Reads from a socket.

Args:
sockfd: The id of the socket that will be read from.
data: The storage array for data read from the socket.
len: The length of the data in bytes.
*/

void readbuffer_socket( int sockfd, void *data, int len )
{
int n, nr;
char *pdata;

pdata = (char *) data;
n = nr = read(sockfd, pdata, len);

while (nr > 0 && n < len) {
nr = read(sockfd, &(pdata[n]), len - n);
n += nr;
}
if (n == 0) {
perror("Error reading from socket: server has quit or connection broke");
exit(-1);
}
}

///////////////////////////////////////////////////////////////////////////////
/* Shuts down the socket.
*/

void shutdown_socket( int sockfd )
{
shutdown( sockfd, 2 );
close( sockfd );
}

DWORD WINAPI ClientThread(LPVOID lpParameter)
{
SOCKET CientSocket = (SOCKET)lpParameter;
int Ret = 0;
char RecvBuffer[1024];

while ( 1 )
{
memset(RecvBuffer, 0x00, sizeof(RecvBuffer));
Ret = recv(CientSocket, RecvBuffer, 1024, 0);
if ( Ret == 0 || Ret == SOCKET_ERROR )
{
printf("服务端退出!");
break;
}

}
printf("接收到服务端的信息为%s", RecvBuffer);

return 0;
}

int main(int argc, char * argv[])
{
WSADATA Ws;
SOCKET ClientSocket;
struct sockaddr_in ServerAddr;
int Ret = 0;
int AddrLen = 0;
HANDLE hThread = NULL;
char SendBuffer[MAX_PATH];
int str_len;
char RecvBuffer[30];

//Init Windows Socket
if ( WSAStartup(MAKEWORD(2,2), &Ws) != 0 )
{
printf("Init Windows Socket Failed");
return -1;
}
//Create Socket
ClientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if ( ClientSocket == INVALID_SOCKET )
{
printf("Create Socket Failed");
return -1;
}

ServerAddr.sin_family = AF_INET;
ServerAddr.sin_addr.s_addr = inet_addr(IP_ADDRESS);
ServerAddr.sin_port = htons(PORT);
memset(ServerAddr.sin_zero, 0x00, 8);

Ret = connect(ClientSocket,(struct sockaddr*)&ServerAddr, sizeof(ServerAddr));
if ( Ret == SOCKET_ERROR )
{
printf("Connect Error");
return -1;
}
else
{
printf("连接成功!\n");
}

//read(ClientSocket, RecvBuffer, sizeof(RecvBuffer) - 1);
str_len = recv(ClientSocket, RecvBuffer, 30, 0);
RecvBuffer[str_len] = '\0';
printf("Message from server: %s\n", RecvBuffer);

while ( 1 )
{
//cin.getline(SendBuffer, sizeof(SendBuffer));
printf("Enter the Send infos-\n");
scanf("%s", SendBuffer);
Ret = send(ClientSocket, SendBuffer, (int)strlen(SendBuffer), 0);
if ( Ret == SOCKET_ERROR )
{
printf("Send Info Error");
break;
}

/*
hThread = CreateThread(NULL, 0, ClientThread, (LPVOID)ClientSocket, 0, NULL);
if ( hThread == NULL )
{
printf("Create Thread Failed!");
break;
}

CloseHandle(hThread);
*/
printf("开始接收!");
//str_len = read(ClientSocket, RecvBuffer, sizeof(RecvBuffer) - 1);
//str_len = read(ClientSocket, RecvBuffer, sizeof(RecvBuffer) - 1);
//str_len = read(ClientSocket, RecvBuffer, sizeof(RecvBuffer) - 1);
str_len = recv(ClientSocket, RecvBuffer, 30, 0);
if (str_len == -1)
printf("read() error!");
else
printf("接受到的返回消息:%s",RecvBuffer);
}

closesocket(ClientSocket);
WSACleanup();

return 0;
}

C语言写了一个socket client端,适合windows和linux,用GCC编译运行通过的更多相关文章

  1. C语言写了一个socket server端,适合windows和linux,用GCC编译运行通过

    ////////////////////////////////////////////////////////////////////////////////* gcc -Wall -o s1 s1 ...

  2. 第一个socket服务端程序

    第一个socket服务端程序 #include <stdio.h> #include <stdlib.h> #include <string.h> #include ...

  3. 不好意思啊,我上周到今天不到10天时间,用纯C语言写了一个小站!想拍砖的就赶紧拿出来拍啊

    花10天时间用C语言做了个小站 http://tieba.yunxunmi.com/index.html 简称: 云贴吧 不好意思啊,我上周到今天不到10天时间,用纯C语言写了一个小站!想拍砖的就赶紧 ...

  4. 用Racket语言写了一个万花筒的程序

    用Racket语言写了一个万花筒的程序 来源:https://blog.csdn.net/chinazhangyong/article/details/79362394 https://github. ...

  5. 在Linux使用GCC编译C语言共享库

    在Linux使用GCC编译C语言共享库 对任何程序员来说库都是必不可少的.所谓的库是指已经编译好的供你使用的代码.它们常常提供一些通用功能,例如链表和二叉树可以用来保存任何数据,或者是一个特定的功能例 ...

  6. python - socket - client端指定ip和端口

    问题描述: 在设备中有3个NI, ip分别为192.168.1.5/6/7.其中本端192.168.1.6同对端192.168.1.10建立了一个tunnel. 我希望测试tunnel连通性, 对端起 ...

  7. [Swift通天遁地]四、网络和线程-(14)创建一个Socket服务端

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  8. 使用PHP创建一个socket服务端

    与常规web开发不同,使用socket开发可以摆脱http的限制.可自定义协议,使用长连接.PHP代码常驻内存等.学习资料来源于workerman官方视频与文档. 通常创建一个socket服务包括这几 ...

  9. 在 Linux 使用 GCC 编译C语言共享库

    对任何程序员来说库都是必不可少的.所谓的库是指已经编译好的供你使用的代码.它们常常提供一些通用功能,例如链表和二叉树可以用来保存任何数据,或者是一个特定的功能例如一个数据库服务器的接口,就像MySQL ...

随机推荐

  1. weblogic配置集群(一)

    一.程序安装 二.创建域 好的  篇幅太长  我就接下来的操作就写在下一篇博客了 weblogic配置集群(二)

  2. 通过Windows API实现的MDI简易程序

    ## #include <windows.h> #include <tchar.h> HINSTANCE hInst; ATOM WindowRegister(WNDPROC ...

  3. FPGA之初认识

    什么是FPGA FPGA(Field-Programmable Gate Array),即现场可编程门阵列 .看到编程两个字码农就笑了,不就是编程嘛,那可是我们的强项 .且慢,此编程非彼编程 .一定要 ...

  4. 用Kotlin写一个基于Spring Boot的RESTful服务

    Spring太复杂了,配置这个东西简直就是浪费生命.尤其在没有什么并发压力,随便搞一个RESTful服务 让整个业务跑起来先的情况下,更是么有必要纠结在一堆的XML配置上.显然这么想的人是很多的,于是 ...

  5. 20145232 韩文浩 《Java程序设计》第8周学习总结

    教材学习内容总结 14 NIO与NIO2 NIO使用频道(channel)来衔接数据节点,对数据区的标记提供了clear(),rewind(),flip(),compact()等高级操作. 想要取得c ...

  6. sys/time.h 和 time.h

    今天在燕麦工作第二天.看荣哥给我的程序,发现程序里面用的延时跟我以前使用的不同.导入两个头文件,然后用函数来获得时间.关于这个函数特别查来一下. time.h  是ISO C99 标准日期头文件. s ...

  7. linux ping命令

    Linux系统的ping命令是常用的网络命令,它通常用来测试与目标主机的连通性,我们经常会说“ping一下某机器,看是不是开着”.不能打开网页时会说“你先ping网关地址192.168.1.1试试”. ...

  8. 如何对CentOS FTP服务配置

    根据很多人对CentOS FTP服务的不解,我觉得应该对CentOS FTP服务做出一定的解释. 1.安装 一般在CentOS上都自动安装了vsftd,若没有安装则可以使用以下步骤进行安装yum -y ...

  9. Codeforces Round #298 (Div. 2)--D. Handshakes

    #include <stdio.h> #include <algorithm> #include <set> using namespace std; #defin ...

  10. 10.DataGrid的特性